|
|
478375 |
From 3f3e6b62719a263cb221c19a06d9a2c570234caa Mon Sep 17 00:00:00 2001
|
|
|
478375 |
From: Jan Friesse <jfriesse@redhat.com>
|
|
|
478375 |
Date: Thu, 27 Sep 2018 13:08:48 +0200
|
|
|
478375 |
Subject: [PATCH] totemcrypto: Fix importing of the private key
|
|
|
478375 |
|
|
|
478375 |
Import key with length not dividable by wrap key block size was not
|
|
|
478375 |
possible.
|
|
|
478375 |
|
|
|
478375 |
Wrapping of the key is standard crypto operation which needs data
|
|
|
478375 |
aligned to cipher block size, otherwise it fails.
|
|
|
478375 |
|
|
|
478375 |
Possible solution is to use a zero filled buffer with size aligned to
|
|
|
478375 |
required wrap key block size. Private key is copied to the beginning of
|
|
|
478375 |
the buffer and unwrap operation keeps using only required private key
|
|
|
478375 |
size.
|
|
|
478375 |
|
|
|
478375 |
Signed-off-by: Jan Friesse <jfriesse@redhat.com>
|
|
|
478375 |
Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
|
|
|
478375 |
Reviewed-by: Christine Caulfield <ccaulfie@redhat.com>
|
|
|
478375 |
---
|
|
|
478375 |
exec/totemcrypto.c | 29 +++++++++++++++++++++++++++--
|
|
|
478375 |
1 file changed, 27 insertions(+), 2 deletions(-)
|
|
|
478375 |
|
|
|
478375 |
diff --git a/exec/totemcrypto.c b/exec/totemcrypto.c
|
|
|
478375 |
index 273c567..55763af 100644
|
|
|
478375 |
--- a/exec/totemcrypto.c
|
|
|
478375 |
+++ b/exec/totemcrypto.c
|
|
|
478375 |
@@ -247,7 +247,9 @@ static PK11SymKey *import_symmetric_key(struct crypto_instance *instance, enum s
|
|
|
478375 |
SECItem tmp_sec_item;
|
|
|
478375 |
SECItem wrapped_key;
|
|
|
478375 |
int wrapped_key_len;
|
|
|
478375 |
+ int wrap_key_block_size;
|
|
|
478375 |
unsigned char wrapped_key_data[MAX_WRAPPED_KEY_LEN];
|
|
|
478375 |
+ unsigned char pad_key_data[MAX_WRAPPED_KEY_LEN];
|
|
|
478375 |
int case_processed;
|
|
|
478375 |
|
|
|
478375 |
memset(&key_item, 0, sizeof(key_item));
|
|
|
478375 |
@@ -256,8 +258,15 @@ static PK11SymKey *import_symmetric_key(struct crypto_instance *instance, enum s
|
|
|
478375 |
res_key = NULL;
|
|
|
478375 |
wrap_key_crypt_context = NULL;
|
|
|
478375 |
|
|
|
478375 |
+ if (instance->private_key_len > sizeof(pad_key_data)) {
|
|
|
478375 |
+ log_printf(instance->log_level_security, "Import symmetric key failed. Private key is too long");
|
|
|
478375 |
+ goto exit_res_key;
|
|
|
478375 |
+ }
|
|
|
478375 |
+ memset(pad_key_data, 0, sizeof(pad_key_data));
|
|
|
478375 |
+ memcpy(pad_key_data, instance->private_key, instance->private_key_len);
|
|
|
478375 |
+
|
|
|
478375 |
key_item.type = siBuffer;
|
|
|
478375 |
- key_item.data = instance->private_key;
|
|
|
478375 |
+ key_item.data = pad_key_data;
|
|
|
478375 |
|
|
|
478375 |
case_processed = 0;
|
|
|
478375 |
switch (key_type) {
|
|
|
478375 |
@@ -318,6 +327,22 @@ static PK11SymKey *import_symmetric_key(struct crypto_instance *instance, enum s
|
|
|
478375 |
*/
|
|
|
478375 |
|
|
|
478375 |
/*
|
|
|
478375 |
+ * Key must be padded to a block size
|
|
|
478375 |
+ */
|
|
|
478375 |
+ wrap_key_block_size = PK11_GetBlockSize(wrap_mechanism, 0);
|
|
|
478375 |
+ if (wrap_key_block_size < 0) {
|
|
|
478375 |
+ log_printf(instance->log_level_security, "Unable to get wrap key block size (%d): %s",
|
|
|
478375 |
+ PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT));
|
|
|
478375 |
+ goto exit_res_key;
|
|
|
478375 |
+ }
|
|
|
478375 |
+ if (sizeof(pad_key_data) % wrap_key_block_size != 0) {
|
|
|
478375 |
+ log_printf(instance->log_level_security, "Padded key buffer size (%zu) is not dividable by "
|
|
|
478375 |
+ "wrap key block size (%u).", sizeof(pad_key_data), (unsigned int)wrap_key_block_size);
|
|
|
478375 |
+
|
|
|
478375 |
+ goto exit_res_key;
|
|
|
478375 |
+ }
|
|
|
478375 |
+
|
|
|
478375 |
+ /*
|
|
|
478375 |
* Initialization of IV is not needed because PK11_GetBestWrapMechanism should return ECB mode
|
|
|
478375 |
*/
|
|
|
478375 |
memset(&tmp_sec_item, 0, sizeof(tmp_sec_item));
|
|
|
478375 |
@@ -332,7 +357,7 @@ static PK11SymKey *import_symmetric_key(struct crypto_instance *instance, enum s
|
|
|
478375 |
wrapped_key_len = (int)sizeof(wrapped_key_data);
|
|
|
478375 |
|
|
|
478375 |
if (PK11_CipherOp(wrap_key_crypt_context, wrapped_key_data, &wrapped_key_len,
|
|
|
478375 |
- sizeof(wrapped_key_data), key_item.data, key_item.len) != SECSuccess) {
|
|
|
478375 |
+ sizeof(wrapped_key_data), key_item.data, sizeof(pad_key_data)) != SECSuccess) {
|
|
|
478375 |
log_printf(instance->log_level_security, "Unable to encrypt authkey (%d): %s",
|
|
|
478375 |
PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT));
|
|
|
478375 |
goto exit_res_key;
|
|
|
478375 |
--
|
|
|
478375 |
1.8.3.1
|
|
|
478375 |
|