From 4f7a56d5e02e3d04ab69eac1213817a7536d0562 Mon Sep 17 00:00:00 2001 From: "djm@openbsd.org" Date: Fri, 21 Jun 2019 04:21:04 +0000 Subject: upstream: Add protection for private keys at rest in RAM against speculation and memory sidechannel attacks like Spectre, Meltdown, Rowhammer and Rambleed. This change encrypts private keys when they are not in use with a symmetic key that is derived from a relatively large "prekey" consisting of random data (currently 16KB). Attackers must recover the entire prekey with high accuracy before they can attempt to decrypt the shielded private key, but the current generation of attacks have bit error rates that, when applied cumulatively to the entire prekey, make this unlikely. Implementation-wise, keys are encrypted "shielded" when loaded and then automatically and transparently unshielded when used for signatures or when being saved/serialised. Hopefully we can remove this in a few years time when computer architecture has become less unsafe. been in snaps for a bit already; thanks deraadt@ ok dtucker@ deraadt@ OpenBSD-Commit-ID: 19767213c312e46f94b303a512ef8e9218a39bd4 --- sshkey.h | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'sshkey.h') diff --git a/sshkey.h b/sshkey.h index a91e60436..41d159a1b 100644 --- a/sshkey.h +++ b/sshkey.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sshkey.h,v 1.31 2019/01/20 22:51:37 djm Exp $ */ +/* $OpenBSD: sshkey.h,v 1.32 2019/06/21 04:21:05 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -123,6 +123,10 @@ struct sshkey { u_char *xmss_sk; u_char *xmss_pk; struct sshkey_cert *cert; + u_char *shielded_private; + size_t shielded_len; + u_char *shield_prekey; + size_t shield_prekey_len; }; #define ED25519_SK_SZ crypto_sign_ed25519_SECRETKEYBYTES @@ -146,6 +150,11 @@ u_int sshkey_size(const struct sshkey *); int sshkey_generate(int type, u_int bits, struct sshkey **keyp); int sshkey_from_private(const struct sshkey *, struct sshkey **); + +int sshkey_is_shielded(struct sshkey *); +int sshkey_shield_private(struct sshkey *); +int sshkey_unshield_private(struct sshkey *); + int sshkey_type_from_name(const char *); int sshkey_is_cert(const struct sshkey *); int sshkey_type_is_cert(int); @@ -161,7 +170,7 @@ int sshkey_check_cert_sigtype(const struct sshkey *, const char *); int sshkey_certify(struct sshkey *, struct sshkey *, const char *); /* Variant allowing use of a custom signature function (e.g. for ssh-agent) */ -typedef int sshkey_certify_signer(const struct sshkey *, u_char **, size_t *, +typedef int sshkey_certify_signer(struct sshkey *, u_char **, size_t *, const u_char *, size_t, const char *, u_int, void *); int sshkey_certify_custom(struct sshkey *, struct sshkey *, const char *, sshkey_certify_signer *, void *); @@ -192,7 +201,7 @@ int sshkey_puts_opts(const struct sshkey *, struct sshbuf *, int sshkey_plain_to_blob(const struct sshkey *, u_char **, size_t *); int sshkey_putb_plain(const struct sshkey *, struct sshbuf *); -int sshkey_sign(const struct sshkey *, u_char **, size_t *, +int sshkey_sign(struct sshkey *, u_char **, size_t *, const u_char *, size_t, const char *, u_int); int sshkey_verify(const struct sshkey *, const u_char *, size_t, const u_char *, size_t, const char *, u_int); @@ -204,8 +213,8 @@ void sshkey_dump_ec_point(const EC_GROUP *, const EC_POINT *); void sshkey_dump_ec_key(const EC_KEY *); /* private key parsing and serialisation */ -int sshkey_private_serialize(const struct sshkey *key, struct sshbuf *buf); -int sshkey_private_serialize_opt(const struct sshkey *key, struct sshbuf *buf, +int sshkey_private_serialize(struct sshkey *key, struct sshbuf *buf); +int sshkey_private_serialize_opt(struct sshkey *key, struct sshbuf *buf, enum sshkey_serialize_rep); int sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **keyp); @@ -231,7 +240,7 @@ int sshkey_set_filename(struct sshkey *, const char *); int sshkey_enable_maxsign(struct sshkey *, u_int32_t); u_int32_t sshkey_signatures_left(const struct sshkey *); int sshkey_forward_state(const struct sshkey *, u_int32_t, sshkey_printfn *); -int sshkey_private_serialize_maxsign(const struct sshkey *key, struct sshbuf *buf, +int sshkey_private_serialize_maxsign(struct sshkey *key, struct sshbuf *buf, u_int32_t maxsign, sshkey_printfn *pr); #ifdef SSHKEY_INTERNAL -- cgit v1.2.3