Enable support for DSA and RSA 4096 92/203092/3
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Fri, 5 Apr 2019 15:15:17 +0000 (17:15 +0200)
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Fri, 17 May 2019 12:25:28 +0000 (14:25 +0200)
- 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

ssflib/inc/crypto_internal.h
ssflib/src/ssf_crypto.cpp

index f6b6ad4..33395d1 100644 (file)
@@ -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 */
index dc264cf..31a17ea 100644 (file)
@@ -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 <permission.h>
 #include <array>
 #include <algorithm>
+#include <vector>
 
 #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<std::vector<unsigned char>> 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;
        }