From: Krzysztof Jackiewicz Date: Fri, 5 Apr 2019 15:15:17 +0000 (+0200) Subject: Enable support for DSA and RSA 4096 X-Git-Tag: submit/tizen/20190520.091210~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=532c31bf3ce0f963fbe4c65e290112e087fecc5b;p=platform%2Fcore%2Fsecurity%2Ftef-simulator.git Enable support for DSA and RSA 4096 - Allow creation of DSA operation (sw_crypto_open) - Extract DSA attributes from TEE object and transfer them to crypto core (TEE_AsymmetricSignDigest, TEE_AsymmetricVerifyDigest) reusing RSA key representation (crypto_internal_keystruct). To be refactored. - Properly initialize DSA operation using DSA key parameters (sw_crypto_ioctl_init) - In case of RSA 4096 the buffer size for key attributes is too small. Take attribute size from key size due to lack of length probing in TEE_GetObjectBufferAttribute(). Change-Id: If2b536ea3b5a5cee6d347e36c2be2febcc9db622 --- diff --git a/ssflib/inc/crypto_internal.h b/ssflib/inc/crypto_internal.h index f6b6ad4..33395d1 100644 --- a/ssflib/inc/crypto_internal.h +++ b/ssflib/inc/crypto_internal.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2011-2017 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2011-2019 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -64,14 +64,15 @@ typedef struct unsigned int size; } crypto_internal_keydata; +// TODO: Refactor this struct and related code to support DSA and ECDSA as well typedef struct { crypto_internal_keydata secret; /* TEE_ATTR_SECRET_VALUE */ - crypto_internal_keydata rsa_modulus; /* TEE_ATTR_RSA_MODULUS */ - crypto_internal_keydata rsa_public; /* TEE_ATTR_RSA_PUBLIC_EXPONENT */ - crypto_internal_keydata rsa_private; /* TEE_ATTR_RSA_PRIVATE_EXPONENT */ - crypto_internal_keydata rsa_prime1; /* TEE_ATTR_RSA_PRIME1 */ - crypto_internal_keydata rsa_prime2; /* TEE_ATTR_RSA_PRIME2 */ + crypto_internal_keydata rsa_modulus; /* TEE_ATTR_RSA_MODULUS / TEE_ATTR_DSA_BASE */ + crypto_internal_keydata rsa_public; /* TEE_ATTR_RSA_PUBLIC_EXPONENT / TEE_ATTR_DSA_PUBLIC_VALUE */ + crypto_internal_keydata rsa_private; /* TEE_ATTR_RSA_PRIVATE_EXPONENT / TEE_ATTR_DSA_PRIVATE_VALUE */ + crypto_internal_keydata rsa_prime1; /* TEE_ATTR_RSA_PRIME1 / TEE_ATTR_DSA_PRIME */ + crypto_internal_keydata rsa_prime2; /* TEE_ATTR_RSA_PRIME2 / TEE_ATTR_DSA_SUBPRIME */ crypto_internal_keydata rsa_exponent1; /* TEE_ATTR_RSA_EXPONENT1 */ crypto_internal_keydata rsa_exponent2; /* TEE_ATTR_RSA_EXPONENT2 */ crypto_internal_keydata rsa_coefficient; /* TEE_ATTR_RSA_COEFFICIENT */ diff --git a/ssflib/src/ssf_crypto.cpp b/ssflib/src/ssf_crypto.cpp index dc264cf..31a17ea 100644 --- a/ssflib/src/ssf_crypto.cpp +++ b/ssflib/src/ssf_crypto.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-2017 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2015-2019 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,6 +33,7 @@ #include #include #include +#include #include "CC_API.h" #include "ssf_crypto_openssl.h" @@ -440,16 +441,18 @@ static int sw_crypto_ioctl_init(crypto_internal_operation *operation, crypto_int break; case TEE_ALG_DSA_SHA1: - padding = 0; - rc = handle->RSA_setKeypairForCRT(handle, padding, - key->rsa_modulus.buffer, key->rsa_modulus.size, - key->rsa_public.buffer, key->rsa_public.size, - key->rsa_private.buffer, key->rsa_private.size, + // set prime, subprime and base + rc = handle->DSA_setParam(handle, key->rsa_prime1.buffer, key->rsa_prime1.size, key->rsa_prime2.buffer, key->rsa_prime2.size, - key->rsa_exponent1.buffer, key->rsa_exponent1.size, - key->rsa_exponent2.buffer, key->rsa_exponent2.size, - key->rsa_coefficient.buffer, key->rsa_coefficient.size); + key->rsa_modulus.buffer, key->rsa_modulus.size); + if (rc != 0) + break; + + // set private and public value + rc = handle->DSA_setKeyPair(handle, + key->rsa_public.buffer, key->rsa_public.size, + key->rsa_private.buffer, key->rsa_private.size); break; case TEE_ALG_GENERATE_SECRET_KEY: @@ -654,6 +657,7 @@ static int sw_crypto_ioctl_final(crypto_internal_operation *operation, unsigned case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256: case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384: case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512: + case TEE_ALG_DSA_SHA1: if (operation->info.mode == TEE_MODE_SIGN ) { rc = handle->DS_sign(handle, src_addr, src_size, dst_addr, dst_size); } else { @@ -833,7 +837,7 @@ static int sw_crypto_open(crypto_internal_operation *operation) break; case TEE_ALG_DSA_SHA1: - goto error; + alg = ID_DSA; break; case TEE_ALG_ECDSA_P160: @@ -905,6 +909,20 @@ static int sw_crypto_close(crypto_internal_operation *operation) return rc; } +class BufferProvider +{ +public: + //BufferProvider() = default; + void PrepareBuffer(size_t size, crypto_internal_keydata& data) { + buffers.emplace_back(size, 0x00); + data.size = size; + data.buffer = buffers.back().data(); + } + +private: + std::vector> buffers; +}; + int crypto_internal_open(crypto_internal_operation *operation) { if (operation->info.algorithm == TEE_ALG_AES_GCM || operation->info.algorithm == TEE_ALG_AES_CTR) { @@ -2592,18 +2610,7 @@ TEE_Result TEE_AsymmetricSignDigest( TEE_OperationHandle operation, const TEE_At (void)paramCount; crypto_internal_operation *op = (crypto_internal_operation*) operation; crypto_internal_keystruct key; - - unsigned char module_buf[384] = {0x0, }; - unsigned char pub_buf[384] = {0x0, }; - unsigned char priv_buf[384] = {0x0, }; - - memset(&key, 0x00, sizeof(crypto_internal_keystruct)); - key.rsa_modulus.size = sizeof(module_buf); - key.rsa_modulus.buffer = module_buf; - key.rsa_public.size = sizeof(pub_buf); - key.rsa_public.buffer = pub_buf; - key.rsa_private.size = sizeof(priv_buf); - key.rsa_private.buffer = priv_buf; + TEE_ObjectInfo info; if (op->info.operationClass != TEE_OPERATION_ASYMMETRIC_SIGNATURE) { CRYPTO_PANIC; @@ -2614,45 +2621,87 @@ TEE_Result TEE_AsymmetricSignDigest( TEE_OperationHandle operation, const TEE_At if (!(op->info.handleState & TEE_HANDLE_FLAG_KEY_SET)) { CRYPTO_PANIC; } - if (TEE_GetObjectBufferAttribute(op->key1, TEE_ATTR_RSA_MODULUS, - (void*)key.rsa_modulus.buffer, (size_t*)&key.rsa_modulus.size) != TEE_SUCCESS) { - CRYPTO_PANIC; - } - if (TEE_GetObjectBufferAttribute(op->key1, TEE_ATTR_RSA_PUBLIC_EXPONENT, - (void*)key.rsa_public.buffer, (size_t*)&key.rsa_public.size) != TEE_SUCCESS) { - CRYPTO_PANIC; - } - if (TEE_GetObjectBufferAttribute(op->key1, TEE_ATTR_RSA_PRIVATE_EXPONENT, - (void*)key.rsa_private.buffer, (size_t*)&key.rsa_private.size) != TEE_SUCCESS) { - CRYPTO_PANIC; - } + + TEE_GetObjectInfo(op->key1, &info); + + // TEE_GetObjectBufferAttribute does not allow length probing + size_t maxAttrSize = info.objectSize / 8; + memset(&key, 0x00, sizeof(crypto_internal_keystruct)); + BufferProvider bp; + + switch (info.objectType) { + case TEE_TYPE_RSA_KEYPAIR: + { + bp.PrepareBuffer(maxAttrSize, key.rsa_modulus); + bp.PrepareBuffer(maxAttrSize, key.rsa_private); + + if (TEE_GetObjectBufferAttribute(op->key1, TEE_ATTR_RSA_MODULUS, + (void*) key.rsa_modulus.buffer, (size_t*) &key.rsa_modulus.size) != TEE_SUCCESS) { + CRYPTO_PANIC; + } + if (TEE_GetObjectBufferAttribute(op->key1, TEE_ATTR_RSA_PRIVATE_EXPONENT, + (void*) key.rsa_private.buffer, (size_t*) &key.rsa_private.size) != TEE_SUCCESS) { + CRYPTO_PANIC; + } #if 0 /* Not Support */ - if (TEE_GetObjectBufferAttribute(op->key1, TEE_ATTR_RSA_PRIME1, - (void*)key.rsa_prime1.buffer, (size_t*)&key.rsa_prime1.size) != TEE_SUCCESS) { - CRYPTO_PANIC; - } - if (TEE_GetObjectBufferAttribute(op->key1, TEE_ATTR_RSA_PRIME2, - (void*)key.rsa_prime2.buffer, (size_t*)&key.rsa_prime2.size) != TEE_SUCCESS) { - CRYPTO_PANIC; - } - if (TEE_GetObjectBufferAttribute(op->key1, TEE_ATTR_RSA_EXPONENT1, - (void*)key.rsa_exponent1.buffer, (size_t*)&key.rsa_exponent1.size) != TEE_SUCCESS) { - CRYPTO_PANIC; - } - if (TEE_GetObjectBufferAttribute(op->key1, TEE_ATTR_RSA_EXPONENT2, - (void*)key.rsa_exponent2.buffer, (size_t*)&key.rsa_exponent2.size) != TEE_SUCCESS) { - CRYPTO_PANIC; + if (TEE_GetObjectBufferAttribute(op->key1, TEE_ATTR_RSA_PRIME1, + (void*)key.rsa_prime1.buffer, (size_t*)&key.rsa_prime1.size) != TEE_SUCCESS) { + CRYPTO_PANIC; + } + if (TEE_GetObjectBufferAttribute(op->key1, TEE_ATTR_RSA_PRIME2, + (void*)key.rsa_prime2.buffer, (size_t*)&key.rsa_prime2.size) != TEE_SUCCESS) { + CRYPTO_PANIC; + } + if (TEE_GetObjectBufferAttribute(op->key1, TEE_ATTR_RSA_EXPONENT1, + (void*)key.rsa_exponent1.buffer, (size_t*)&key.rsa_exponent1.size) != TEE_SUCCESS) { + CRYPTO_PANIC; + } + if (TEE_GetObjectBufferAttribute(op->key1, TEE_ATTR_RSA_EXPONENT2, + (void*)key.rsa_exponent2.buffer, (size_t*)&key.rsa_exponent2.size) != TEE_SUCCESS) { + CRYPTO_PANIC; + } + if (TEE_GetObjectBufferAttribute(op->key1, TEE_ATTR_RSA_COEFFICIENT, + (void*)key.rsa_coefficient.buffer, (size_t*)&key.rsa_coefficient.size) != TEE_SUCCESS) { + CRYPTO_PANIC; + } +#endif + if (!key.rsa_modulus.buffer || !key.rsa_private.buffer /*|| !key.rsa_public.buffer + || !key.rsa_prime1.buffer || !key.rsa_prime2.buffer || !key.rsa_exponent1.buffer + || !key.rsa_exponent2.buffer || !key.rsa_coefficient.buffer*/) { + CRYPTO_PANIC; + } + break; } - if (TEE_GetObjectBufferAttribute(op->key1, TEE_ATTR_RSA_COEFFICIENT, - (void*)key.rsa_coefficient.buffer, (size_t*)&key.rsa_coefficient.size) != TEE_SUCCESS) { - CRYPTO_PANIC; + case TEE_TYPE_DSA_KEYPAIR: + { + bp.PrepareBuffer(maxAttrSize, key.rsa_prime1); + bp.PrepareBuffer(maxAttrSize, key.rsa_prime2); + bp.PrepareBuffer(maxAttrSize, key.rsa_modulus); + bp.PrepareBuffer(maxAttrSize, key.rsa_private); + + if (TEE_GetObjectBufferAttribute(op->key1, TEE_ATTR_DSA_PRIME, + (void*) key.rsa_prime1.buffer, (size_t*) &key.rsa_prime1.size) != TEE_SUCCESS) { + CRYPTO_PANIC; + } + if (TEE_GetObjectBufferAttribute(op->key1, TEE_ATTR_DSA_SUBPRIME, + (void*) key.rsa_prime2.buffer, (size_t*) &key.rsa_prime2.size) != TEE_SUCCESS) { + CRYPTO_PANIC; + } + if (TEE_GetObjectBufferAttribute(op->key1, TEE_ATTR_DSA_BASE, + (void*) key.rsa_modulus.buffer, (size_t*) &key.rsa_modulus.size) != TEE_SUCCESS) { + CRYPTO_PANIC; + } + if (TEE_GetObjectBufferAttribute(op->key1, TEE_ATTR_DSA_PRIVATE_VALUE, + (void*) key.rsa_private.buffer, (size_t*) &key.rsa_private.size) != TEE_SUCCESS) { + CRYPTO_PANIC; + } + + break; } -#endif - if(!key.rsa_modulus.buffer || !key.rsa_public.buffer || !key.rsa_private.buffer - /*|| !key.rsa_prime1.buffer || !key.rsa_prime2.buffer || !key.rsa_exponent1.buffer - || !key.rsa_exponent2.buffer || !key.rsa_coefficient.buffer*/) { + default: CRYPTO_PANIC; } + if (crypto_internal_init(op, &key, NULL, 0)) { CRYPTO_PANIC; } @@ -2676,15 +2725,7 @@ TEE_Result TEE_AsymmetricVerifyDigest( TEE_OperationHandle operation, const TEE_ crypto_internal_operation *op = (crypto_internal_operation*) operation; crypto_internal_keystruct key; size_t sign_len=signatureLen; - - unsigned char module_buf[384] = {0x0, }; - unsigned char pub_buf[384] = {0x0, }; - - memset(&key, 0x00, sizeof(crypto_internal_keystruct)); - key.rsa_modulus.size = sizeof(module_buf); - key.rsa_modulus.buffer = module_buf; - key.rsa_public.size = sizeof(pub_buf); - key.rsa_public.buffer = pub_buf; + TEE_ObjectInfo info; if (op->info.operationClass != TEE_OPERATION_ASYMMETRIC_SIGNATURE) { CRYPTO_PANIC; @@ -2695,17 +2736,65 @@ TEE_Result TEE_AsymmetricVerifyDigest( TEE_OperationHandle operation, const TEE_ if (!(op->info.handleState & TEE_HANDLE_FLAG_KEY_SET)) { CRYPTO_PANIC; } - if (TEE_GetObjectBufferAttribute(op->key1, TEE_ATTR_RSA_MODULUS, - (void*)key.rsa_modulus.buffer, (size_t*)&key.rsa_modulus.size) != TEE_SUCCESS) { - CRYPTO_PANIC; + + TEE_GetObjectInfo(op->key1, &info); + + // TEE_GetObjectBufferAttribute does not allow length probing + size_t maxAttrSize = info.objectSize / 8; + + memset(&key, 0x00, sizeof(crypto_internal_keystruct)); + BufferProvider bp; + + switch (info.objectType) { + case TEE_TYPE_RSA_PUBLIC_KEY: + case TEE_TYPE_RSA_KEYPAIR: + { + bp.PrepareBuffer(maxAttrSize, key.rsa_modulus); + bp.PrepareBuffer(maxAttrSize, key.rsa_public); + + if (TEE_GetObjectBufferAttribute(op->key1, TEE_ATTR_RSA_MODULUS, + (void*)key.rsa_modulus.buffer, (size_t*)&key.rsa_modulus.size) != TEE_SUCCESS) { + CRYPTO_PANIC; + } + if (TEE_GetObjectBufferAttribute(op->key1, TEE_ATTR_RSA_PUBLIC_EXPONENT, + (void*)key.rsa_public.buffer, (size_t*)&key.rsa_public.size) != TEE_SUCCESS) { + CRYPTO_PANIC; + } + if(!key.rsa_modulus.buffer || !key.rsa_public.buffer ) { + CRYPTO_PANIC; + } + break; } - if (TEE_GetObjectBufferAttribute(op->key1, TEE_ATTR_RSA_PUBLIC_EXPONENT, - (void*)key.rsa_public.buffer, (size_t*)&key.rsa_public.size) != TEE_SUCCESS) { - CRYPTO_PANIC; + case TEE_TYPE_DSA_PUBLIC_KEY: + case TEE_TYPE_DSA_KEYPAIR: + { + bp.PrepareBuffer(maxAttrSize, key.rsa_prime1); + bp.PrepareBuffer(maxAttrSize, key.rsa_prime2); + bp.PrepareBuffer(maxAttrSize, key.rsa_modulus); + bp.PrepareBuffer(maxAttrSize, key.rsa_public); + + if (TEE_GetObjectBufferAttribute(op->key1, TEE_ATTR_DSA_PRIME, + (void*) key.rsa_prime1.buffer, (size_t*) &key.rsa_prime1.size) != TEE_SUCCESS) { + CRYPTO_PANIC; + } + if (TEE_GetObjectBufferAttribute(op->key1, TEE_ATTR_DSA_SUBPRIME, + (void*) key.rsa_prime2.buffer, (size_t*) &key.rsa_prime2.size) != TEE_SUCCESS) { + CRYPTO_PANIC; + } + if (TEE_GetObjectBufferAttribute(op->key1, TEE_ATTR_DSA_BASE, + (void*) key.rsa_modulus.buffer, (size_t*) &key.rsa_modulus.size) != TEE_SUCCESS) { + CRYPTO_PANIC; + } + if (TEE_GetObjectBufferAttribute(op->key1, TEE_ATTR_DSA_PUBLIC_VALUE, + (void*) key.rsa_public.buffer, (size_t*) &key.rsa_public.size) != TEE_SUCCESS) { + CRYPTO_PANIC; + } + break; } - if(!key.rsa_modulus.buffer || !key.rsa_public.buffer ) { + default: CRYPTO_PANIC; } + if (crypto_internal_init(op, &key, NULL, 0)) { CRYPTO_PANIC; }