Implement hash selection in RSA OAEP 59/299259/3
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Fri, 22 Sep 2023 09:34:54 +0000 (11:34 +0200)
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Mon, 25 Sep 2023 19:43:47 +0000 (21:43 +0200)
Change-Id: Iba9c772d5c8fd07368e00100c3b215c5fbf732a5

ta/src/cmd_exec.c

index f7dac3bfada560e28295ea6b70e7897bc639b602..1d95e02a2ca393501c392b1f0a5652d28c07d975 100644 (file)
@@ -72,19 +72,30 @@ static uint32_t KM_EncFlag2TeeMode(int cmd)
        }
 }
 
-
-static uint32_t KM_Algo2TeeAlgo(int algo)
+static uint32_t KM_Algo2TeeAlgoWithHash(int algo, int oaepHash)
 {
        switch (algo) {
        case ALGO_AES_CTR: return TEE_ALG_AES_CTR;
        case ALGO_AES_CBC: return TEE_ALG_AES_CBC_NOPAD;
        case ALGO_AES_CFB: return KM_TA_ALG_AES_CFB;
        case ALGO_AES_GCM: return TEE_ALG_AES_GCM;
-       case ALGO_RSA: return TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1;
+       case ALGO_RSA:
+               switch (oaepHash) {
+                       case HASH_SHA1:   return TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1;
+                       case HASH_SHA256: return TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256;
+                       //case HASH_SHA384: return TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384;
+                       //case HASH_SHA512: return TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512;
+                       default: return 0;
+               }
        default: return 0;
        }
 }
 
+static uint32_t KM_Algo2TeeAlgo(int algo)
+{
+       return KM_Algo2TeeAlgoWithHash(algo, -1);
+}
+
 static uint32_t KM_IsAsymCryptoKeyCorrect(uint32_t commandID, TEE_ObjectHandle key)
 {
        TEE_ObjectInfo info;
@@ -206,7 +217,11 @@ static uint32_t KM_CheckAlgoKeyType(uint32_t algo, uint32_t key_type)
                        return 0;
                }
        }
-       case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1: {
+       case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1:
+       case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256:
+       //case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384:
+       //case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512:
+       {
                switch (key_type) {
                case TEE_TYPE_RSA_KEYPAIR:
                case TEE_TYPE_RSA_PUBLIC_KEY:
@@ -1250,12 +1265,13 @@ clean:
 
 static TEE_Result KM_DoCipherWrappedKeyWithRsa(TEE_ObjectHandle wkey,
                                                                        uint32_t algo, uint32_t tee_enc_mode,
+                                                                       uint32_t oaep_hash,
                                                                        KM_BinaryData *input,
                                                                        KM_BinaryData *output)
 {
        TEE_Result ret = TEE_SUCCESS;
        TEE_OperationHandle operation = TEE_HANDLE_NULL;
-       uint32_t tee_algo = KM_Algo2TeeAlgo(algo);
+       uint32_t tee_algo = KM_Algo2TeeAlgoWithHash(algo, oaep_hash);
 
        void *out = NULL;
        uint32_t out_size = KM_RSA_BLOCK_SIZE;
@@ -1490,6 +1506,7 @@ TEE_Result KM_ExecCmdImportWrappedKey(TEE_Param param[4])
        uint32_t enc_key_type = 0;
        uint32_t tee_enc_key_type = 0;
        uint32_t tee_enc_mode = TEE_MODE_DECRYPT;
+       uint32_t oaep_hash = HASH_SHA1;
 
        void *in_buffer = param[1].memref.buffer;
        void *out_buffer = param[2].memref.buffer;
@@ -1514,19 +1531,26 @@ TEE_Result KM_ExecCmdImportWrappedKey(TEE_Param param[4])
                return TEE_ERROR_BAD_PARAMETERS;
        }
 
-       if (KM_DeserializeBinaryData(&in_buffer, &in_size_guard, &iv)) {
-               LOG("Error in deserialization");
-               return TEE_ERROR_BAD_PARAMETERS;
-       }
+       if (algo == ALGO_RSA) {
+               if (KM_DeserializeFlag(&in_buffer, &in_size_guard, &oaep_hash)) {
+                       LOG("Failed to deserialize oaep_hash flag");
+                       return TEE_ERROR_BAD_PARAMETERS;
+               }
+       } else {
+               if (KM_DeserializeBinaryData(&in_buffer, &in_size_guard, &iv)) {
+                       LOG("Error in deserialization");
+                       return TEE_ERROR_BAD_PARAMETERS;
+               }
 
-       if (KM_DeserializeFlag(&in_buffer, &in_size_guard, &ctr_len_or_tag_size_bits)) {
-               LOG("Failed to deserialize ctr_len_or_tag_size_bits flag");
-               return TEE_ERROR_BAD_PARAMETERS;
-       }
+               if (KM_DeserializeFlag(&in_buffer, &in_size_guard, &ctr_len_or_tag_size_bits)) {
+                       LOG("Failed to deserialize ctr_len_or_tag_size_bits flag");
+                       return TEE_ERROR_BAD_PARAMETERS;
+               }
 
-       if (KM_DeserializeBinaryData(&in_buffer, &in_size_guard, &aad)) {
-               LOG("Error in deserialization");
-               return TEE_ERROR_BAD_PARAMETERS;
+               if (KM_DeserializeBinaryData(&in_buffer, &in_size_guard, &aad)) {
+                       LOG("Error in deserialization");
+                       return TEE_ERROR_BAD_PARAMETERS;
+               }
        }
 
        if (KM_DeserializeFlag(&in_buffer, &in_size_guard, &enc_key_type)) {
@@ -1566,7 +1590,7 @@ TEE_Result KM_ExecCmdImportWrappedKey(TEE_Param param[4])
        }
        TEE_GetObjectInfo(wkey, &wkey_info);
 
-       if(!KM_CheckAlgoKeyType(KM_Algo2TeeAlgo(algo), wkey_info.objectType) ) {
+       if(!KM_CheckAlgoKeyType(KM_Algo2TeeAlgoWithHash(algo, oaep_hash), wkey_info.objectType) ) {
                LOG("Invalid algo & objectType. algo=%x,objectType=%x", KM_Algo2TeeAlgo(algo), wkey_info.objectType);
                ret = TEE_ERROR_BAD_PARAMETERS;
                goto clean;
@@ -1574,7 +1598,7 @@ TEE_Result KM_ExecCmdImportWrappedKey(TEE_Param param[4])
 
        // Do unwrapping
        if (algo == ALGO_RSA) {
-               ret = KM_DoCipherWrappedKeyWithRsa(wkey, algo, tee_enc_mode, &enc_key, &ekey_data);
+               ret = KM_DoCipherWrappedKeyWithRsa(wkey, algo, tee_enc_mode, oaep_hash, &enc_key, &ekey_data);
        } else if (algo == ALGO_AES_GCM) {
                ret = KM_DoCipherWrappedKeyWithAesGcm(wkey, algo, tee_enc_mode, &iv, &aad, ctr_len_or_tag_size_bits, &enc_key, &ekey_data);
        } else {
@@ -1643,6 +1667,7 @@ TEE_Result KM_ExecCmdExportWrappedKey(TEE_Param param[4])
        uint32_t algo = 0;
        uint32_t ctr_len_or_tag_size_bits = 0;
        uint32_t tee_enc_mode = TEE_MODE_ENCRYPT;
+       uint32_t oaep_hash = HASH_SHA1;
 
        void *in_buffer = param[1].memref.buffer;
        void *out_buffer = param[2].memref.buffer;
@@ -1666,19 +1691,26 @@ TEE_Result KM_ExecCmdExportWrappedKey(TEE_Param param[4])
                return TEE_ERROR_BAD_PARAMETERS;
        }
 
-       if (KM_DeserializeBinaryData(&in_buffer, &in_size_guard, &iv)) {
-               LOG("Error in deserialization");
-               return TEE_ERROR_BAD_PARAMETERS;
-       }
+       if (algo == ALGO_RSA) {
+               if (KM_DeserializeFlag(&in_buffer, &in_size_guard, &oaep_hash)) {
+                       LOG("Failed to deserialize oaep_hash flag");
+                       return TEE_ERROR_BAD_PARAMETERS;
+               }
+       } else {
+               if (KM_DeserializeBinaryData(&in_buffer, &in_size_guard, &iv)) {
+                       LOG("Error in deserialization");
+                       return TEE_ERROR_BAD_PARAMETERS;
+               }
 
-       if (KM_DeserializeFlag(&in_buffer, &in_size_guard, &ctr_len_or_tag_size_bits)) {
-               LOG("Failed to deserialize ctr_len_or_tag_size_bits flag");
-               return TEE_ERROR_BAD_PARAMETERS;
-       }
+               if (KM_DeserializeFlag(&in_buffer, &in_size_guard, &ctr_len_or_tag_size_bits)) {
+                       LOG("Failed to deserialize ctr_len_or_tag_size_bits flag");
+                       return TEE_ERROR_BAD_PARAMETERS;
+               }
 
-       if (KM_DeserializeBinaryData(&in_buffer, &in_size_guard, &aad)) {
-               LOG("Error in deserialization");
-               return TEE_ERROR_BAD_PARAMETERS;
+               if (KM_DeserializeBinaryData(&in_buffer, &in_size_guard, &aad)) {
+                       LOG("Error in deserialization");
+                       return TEE_ERROR_BAD_PARAMETERS;
+               }
        }
 
        if (KM_DeserializeBinaryData(&in_buffer, &in_size_guard, &ktw_id)) {
@@ -1701,7 +1733,7 @@ TEE_Result KM_ExecCmdExportWrappedKey(TEE_Param param[4])
        }
        TEE_GetObjectInfo(wkey, &wkey_info);
 
-       if(!KM_CheckAlgoKeyType(KM_Algo2TeeAlgo(algo), wkey_info.objectType) ) {
+       if(!KM_CheckAlgoKeyType(KM_Algo2TeeAlgoWithHash(algo, oaep_hash), wkey_info.objectType) ) {
                LOG("Invalid algo & objectType. algo=%x,objectType=%x", KM_Algo2TeeAlgo(algo), wkey_info.objectType);
                ret = TEE_ERROR_BAD_PARAMETERS;
                goto clean;
@@ -1717,7 +1749,7 @@ TEE_Result KM_ExecCmdExportWrappedKey(TEE_Param param[4])
        // Do wrapping
        // Get Wrapping Key. The Wrapping Key can be symmetric key or Generic Secret Data or RSA Public Key.
        if (algo == ALGO_RSA) {
-               ret = KM_DoCipherWrappedKeyWithRsa(wkey, algo, tee_enc_mode, &ktw_data, &wrapped_key);
+               ret = KM_DoCipherWrappedKeyWithRsa(wkey, algo, tee_enc_mode, oaep_hash, &ktw_data, &wrapped_key);
        } else if (algo == ALGO_AES_GCM) {
                ret = KM_DoCipherWrappedKeyWithAesGcm(wkey, algo, tee_enc_mode, &iv, &aad, ctr_len_or_tag_size_bits, &ktw_data, &wrapped_key);
        } else {
@@ -2063,11 +2095,12 @@ TEE_Result KM_ExecCmdAsymmetric(uint32_t commandID, TEE_Param param[4])
        KM_BinaryData input_data;
        uint32_t with_pwd = 0;
        KM_PwdData pwd_data;
+       uint32_t oaep_hash;
 
        void *out = NULL;
        uint32_t out_size = KM_RSA_BLOCK_SIZE;
 
-       uint32_t algo = KM_Algo2TeeAlgo(param[0].value.a);
+       uint32_t algo;
        uint32_t mode = KM_Cmd2TeeMode(commandID);
 
        void *in_buffer = param[1].memref.buffer;
@@ -2075,11 +2108,6 @@ TEE_Result KM_ExecCmdAsymmetric(uint32_t commandID, TEE_Param param[4])
        uint32_t in_size_guard = param[1].memref.size;
        uint32_t out_size_guard = param[2].memref.size;
 
-       if (algo == 0) {
-               LOG("Unsupported algorithm provided: %u", algo);
-               return TEE_ERROR_BAD_PARAMETERS;
-       }
-
        if (KM_DeserializeBinaryData(&in_buffer, &in_size_guard, &input_data)) {
                LOG("Error in deserialization");
                ret = TEE_ERROR_BAD_PARAMETERS;
@@ -2093,6 +2121,18 @@ TEE_Result KM_ExecCmdAsymmetric(uint32_t commandID, TEE_Param param[4])
                goto clean;
        }
 
+       if (KM_DeserializeFlag(&in_buffer, &in_size_guard, &oaep_hash)) {
+               LOG("Error in deserialization");
+               ret = TEE_ERROR_BAD_PARAMETERS;
+               goto clean;
+       }
+
+       algo = KM_Algo2TeeAlgoWithHash(param[0].value.a, oaep_hash);
+       if (algo == 0) {
+               LOG("Unsupported algorithm provided: %u", algo);
+               return TEE_ERROR_BAD_PARAMETERS;
+       }
+
        if (KM_DeserializeBinaryData(&in_buffer, &in_size_guard, &key_id)) {
                LOG("Error in deserialization");
                ret = TEE_ERROR_BAD_PARAMETERS;