diff options
author | Simo Sorce <simo@redhat.com> | 2018-10-03 13:12:38 -0400 |
---|---|---|
committer | Simo Sorce <simo@redhat.com> | 2018-11-30 13:51:24 -0500 |
commit | 4804febddc2ed958e5ae774de2a8f85edeeff538 (patch) | |
tree | a7a693c3e8fb686581425217d0545b85612616c5 /lib/privkey.c | |
parent | ed3bdddab73c792364deec423b2c2c498a939a64 (diff) | |
download | gnutls-4804febddc2ed958e5ae774de2a8f85edeeff538.tar.gz |
Constant time/cache PKCS#1 RSA decryptiontmp-fix-CVE-2018-16868
This patch tries to make the code have the same time and memory access
aptterns across all branches of the decryption function so that timining
or cache side channels are minimized or neutralized.
To do so it uses a new nettle rsa decryption function that is
side-channel silent.
Signed-off-by: Simo Sorce <simo@redhat.com>
Diffstat (limited to 'lib/privkey.c')
-rw-r--r-- | lib/privkey.c | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/lib/privkey.c b/lib/privkey.c index 26e3cee893..55bd3181ab 100644 --- a/lib/privkey.c +++ b/lib/privkey.c @@ -1555,6 +1555,82 @@ gnutls_privkey_decrypt_data(gnutls_privkey_t key, } /** + * gnutls_privkey_decrypt_data2: + * @key: Holds the key + * @flags: zero for now + * @ciphertext: holds the data to be decrypted + * @plaintext: a preallocated buffer that will be filled with the plaintext + * @plaintext_size: in/out size of the plaintext + * + * This function will decrypt the given data using the algorithm + * supported by the private key. Unlike with gnutls_privkey_decrypt_data() + * this function operates in constant time and constant memory access. + * + * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a + * negative error value. + * + * Since: 3.6.5 + **/ + +int +gnutls_privkey_decrypt_data2(gnutls_privkey_t key, + unsigned int flags, + const gnutls_datum_t * ciphertext, + unsigned char * plaintext, + size_t plaintext_size) +{ + /* Note: except for the backwards compatibility function, no + * conditional code should be called after the decryption + * function call, to avoid creating oracle attacks based + * on cache/timing side channels */ + + /* backwards compatibility */ + if (key->type == GNUTLS_PRIVKEY_EXT && + key->key.ext.decrypt_func2 == NULL && + key->key.ext.decrypt_func != NULL) { + gnutls_datum_t plain; + int ret; + ret = key->key.ext.decrypt_func(key, + key->key.ext.userdata, + ciphertext, + &plain); + if (plain.size != plaintext_size) { + ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); + } else { + memcpy(plaintext, plain.data, plain.size); + } + gnutls_free(plain.data); + return ret; + } + + switch (key->type) { + case GNUTLS_PRIVKEY_X509: + return _gnutls_pk_decrypt2(key->pk_algorithm, ciphertext, + plaintext, plaintext_size, + &key->key.x509->params); +#ifdef ENABLE_PKCS11 + case GNUTLS_PRIVKEY_PKCS11: + return _gnutls_pkcs11_privkey_decrypt_data2(key->key.pkcs11, + flags, + ciphertext, + plaintext, + plaintext_size); +#endif + case GNUTLS_PRIVKEY_EXT: + if (key->key.ext.decrypt_func2 == NULL) + return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); + + return key->key.ext.decrypt_func2(key, + key->key.ext.userdata, + ciphertext, plaintext, + plaintext_size); + default: + gnutls_assert(); + return GNUTLS_E_INVALID_REQUEST; + } +} + +/** * gnutls_privkey_import_x509_raw: * @pkey: The private key * @data: The private key data to be imported |