aboutsummaryrefslogtreecommitdiff
path: root/rpc_pkey.c
diff options
context:
space:
mode:
authorRob Austein <sra@hactrn.net>2017-04-06 21:16:38 -0400
committerRob Austein <sra@hactrn.net>2017-04-06 21:16:38 -0400
commit1386e9b75feeff4ed5446b0169d286e54d7317ff (patch)
tree30124c5509a546057ed5c55ab1620904808b0682 /rpc_pkey.c
parent3828bd1d72c5fd3d3e0bac4548aee9594f63b3ca (diff)
Defend against Bleichenbacher's Attack in hal_rpc_pkey_import().
Borrowing an idea from PyCrypto, we substitute CSPRNG output for the value of a decrypted KEK if the PKCS #1.5 type 02 block format check fails. Done properly, this should be very close to constant-time, and should make it harder to use hal_rpc_pkey_import() as an oracle.
Diffstat (limited to 'rpc_pkey.c')
-rw-r--r--rpc_pkey.c11
1 files changed, 5 insertions, 6 deletions
diff --git a/rpc_pkey.c b/rpc_pkey.c
index ce67614..9473ec3 100644
--- a/rpc_pkey.c
+++ b/rpc_pkey.c
@@ -1217,14 +1217,13 @@ static hal_error_t pkey_local_import(const hal_client_handle_t client,
if ((err = hal_rsa_decrypt(NULL, rsa, data, data_len, der, data_len)) != HAL_OK)
goto fail;
- d = memchr(der + 2, 0x00, data_len - 2);
-
- if (der[0] != 0x00 || der[1] != 0x02 || d == NULL || der + data_len != d + 1 + KEK_LENGTH) {
- err = HAL_ERROR_ASN1_PARSE_FAILED;
+ if ((err = hal_get_random(NULL, kek, sizeof(kek))) != HAL_OK)
goto fail;
- }
- memcpy(kek, d + 1, sizeof(kek));
+ d = memchr(der + 2, 0x00, data_len - 2);
+
+ if (der[0] == 0x00 && der[1] == 0x02 && d != NULL && der + data_len == d + 1 + KEK_LENGTH)
+ memcpy(kek, d + 1, sizeof(kek));
if ((err = hal_asn1_decode_pkcs8_encryptedprivatekeyinfo(&oid, &oid_len, &data, &data_len, pkcs8, pkcs8_len)) != HAL_OK)
goto fail;