add sign, verify functions with ecdsa
authorisaac2.lee <isaac2.lee@samsung.com>
Tue, 25 Oct 2022 01:14:37 +0000 (10:14 +0900)
committerisaac2.lee <isaac2.lee@samsung.com>
Tue, 1 Nov 2022 05:42:15 +0000 (14:42 +0900)
include/key-manager-se-backend.h
srcs/km_se_backend.c
tests/test_cases.cpp

index 62dbf77..e121ff5 100644 (file)
@@ -260,10 +260,10 @@ typedef struct __kmsb_sign_param {
  *                                      or this operation is not supported
  *             - KMSB_ERROR_OPERATION_FAILED: when operation fails with unknown reason
  */
-int kmsb_create_signature(const unsigned int key_idx,
-                const kmsb_sign_param_s *param,
-                const unsigned char *msg, const unsigned int msg_len,
-                unsigned char **sig, unsigned int *sig_len);
+kmsb_error_e kmsb_create_signature(const unsigned int key_idx,
+                    const kmsb_sign_param_s *param,
+                    const unsigned char *msg, const unsigned int msg_len,
+                    unsigned char **sig, unsigned int *sig_len);
 
 /*
  * @brief   Verify signature
@@ -283,10 +283,10 @@ int kmsb_create_signature(const unsigned int key_idx,
  *                                      or this operation is not supported
  *             - KMSB_ERROR_OPERATION_FAILED: when operation fails with unknown reason
  */
-int kmsb_verify_signature(const unsigned int key_idx,
-                const kmsb_sign_param_s *param,
-                const unsigned char *msg, const unsigned int msg_len,
-                unsigned char *sig, unsigned int sig_len);
+kmsb_error_e kmsb_verify_signature(const unsigned int key_idx,
+                    const kmsb_sign_param_s *param,
+                    const unsigned char *msg, const unsigned int msg_len,
+                    unsigned char *sig, unsigned int sig_len);
 
 /*
  * @brief   Get a key value from SE
index 7b5d1ff..11dbab8 100644 (file)
@@ -30,6 +30,7 @@
 #include <string.h>
 #include <stdbool.h>
 #include <openssl/aes.h>
+#include <openssl/ec.h>
 #include <openssl/evp.h>
 #include <openssl/rand.h>
 
@@ -41,7 +42,9 @@
 enum {
     DBP_KEY_IDX = 0,
     AES_KEY_IDX,
-    ECDSA_KEY_IDX,
+    EC_P192_KEY_IDX,
+    EC_P256_KEY_IDX,
+    EC_S384_KEY_IDX,
 } KEY_INDEX;
 
 #define MAX_SLOT_INDEX  8
@@ -50,7 +53,6 @@ static unsigned char *KEY_ARRAY[MAX_SLOT_INDEX] = {NULL,};
 
 const size_t DBP_KEY_SIZE = 32;
 const size_t AES_KEY_SIZE = 32;
-const size_t ECDSA_KEY_SIZE = 32;
 const size_t BLOCK_SIZE = 16;
 const int32_t EVP_SUCCESS = 1;
 
@@ -60,7 +62,6 @@ const int32_t EVP_SUCCESS = 1;
     if(buf) free(buf); \
     return result; \
     }
-
 #define FREE_OUT(buf, result) \
     { \
     if(buf) free(buf); \
@@ -149,21 +150,54 @@ static kmsb_error_e generate_aes_key(const unsigned int key_idx,
     return KMSB_ERROR_NONE;
 }
 
-static kmsb_error_e generate_ecdsa_key(const unsigned int key_idx,
-                                            const bool delete_old)
+static kmsb_error_e generate_ecdsa_key(const unsigned int key_idx, 
+                        kmsb_ec_type_e ec, const bool delete_old)
 {
     if (!delete_old && KEY_ARRAY[key_idx])
         return KMSB_ERROR_NOT_PERMITTED;
 
-    if (!KEY_ARRAY[key_idx]) {
-        KEY_ARRAY[key_idx]= calloc(ECDSA_KEY_SIZE, sizeof(unsigned char));
-    } else {
-        memset(KEY_ARRAY[key_idx], 0, ECDSA_KEY_SIZE);
+    /* Create the context for generating the parameters */
+    EVP_PKEY_CTX *pctx = NULL;
+    EVP_PKEY *pkey = NULL;
+    if (!(pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL)))
+        return KMSB_ERROR_OPERATION_FAILED;
+    if (!EVP_PKEY_paramgen_init(pctx))
+        return KMSB_ERROR_OPERATION_FAILED;
+
+    uint32_t idx = 0;
+    int32_t nid = 0;
+    switch (ec) {
+    case KMSB_EC_PRIME192V1:
+        nid = NID_X9_62_prime192v1;
+        idx = EC_P192_KEY_IDX;
+        break;
+    case KMSB_EC_PRIME256V1:
+        nid = NID_X9_62_prime256v1;
+        idx = EC_P256_KEY_IDX;
+        break;
+    case KMSB_EC_SECP384R1:
+        nid = NID_secp384r1;
+        idx = EC_S384_KEY_IDX;
+        break;
+    default:
+        return KMSB_ERROR_NOT_SUPPORTED;
     }
+    if (idx != key_idx)
+        return KMSB_ERROR_INVALID_PARAMETER;
 
-    if (1 != RAND_bytes(KEY_ARRAY[key_idx], ECDSA_KEY_SIZE))
-        FREE_OUT(KEY_ARRAY[key_idx], KMSB_ERROR_OPERATION_FAILED)
+    /* Use the NID_X9_62_prime256v1 named curve - defined in obj_mac.h */
+    if(!EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, nid))
+        return KMSB_ERROR_OPERATION_FAILED;
 
+    if(!EVP_PKEY_keygen_init(pctx))
+        return KMSB_ERROR_OPERATION_FAILED;
+    /* Generate the key */
+    if (!EVP_PKEY_keygen(pctx, &pkey))
+        return KMSB_ERROR_OPERATION_FAILED;
+    if (pkey == NULL)
+        return KMSB_ERROR_OPERATION_FAILED;
+
+    KEY_ARRAY[key_idx] = (unsigned char*)pkey;
     return KMSB_ERROR_NONE;
 }
 
@@ -437,42 +471,112 @@ kmsb_error_e kmsb_aes_decrypt(const unsigned int key_idx,
     FREE_OUT_CTX(ctx, buf, KMSB_ERROR_NONE)
 }
 
-int kmsb_create_signature(const unsigned int key_idx,
+kmsb_error_e kmsb_create_signature(const unsigned int key_idx,
                 const kmsb_sign_param_s *param,
                 const unsigned char *msg, const unsigned int msg_len,
                 unsigned char **sig, unsigned int *sig_len)
 {
-    // check the validate of key_idx
-    if (key_idx != ECDSA_KEY_IDX) return KMSB_ERROR_INVALID_PARAMETER;
+    kmsb_error_e ret = KMSB_ERROR_NONE;
     if (!KEY_ARRAY[key_idx]) {
-        if (KMSB_ERROR_NONE != generate_ecdsa_key(key_idx, false))
-            return KMSB_ERROR_NO_KEY;
+        ret = generate_ecdsa_key(key_idx, param->ec_type, false);
+        if (KMSB_ERROR_NONE != ret)
+            return ret;
     }
-    (void) param;
-    (void) msg;
-    (void) msg_len;
-    (void) sig;
-    (void) sig_len;
-    return KMSB_ERROR_NOT_SUPPORTED;
+
+    EVP_PKEY *pkey = (EVP_PKEY *)KEY_ARRAY[key_idx];
+    EVP_MD_CTX *mdctx = NULL;
+    /* Create the Message Digest Context */
+    if(!(mdctx = EVP_MD_CTX_create()))
+        return KMSB_ERROR_OPERATION_FAILED;
+
+    switch (param->hash_algo) {
+    case KMSB_HASH_SHA1:
+        if(EVP_SUCCESS != EVP_DigestSignInit(mdctx, NULL, EVP_sha1(), NULL, pkey))
+            return KMSB_ERROR_OPERATION_FAILED;
+        break;
+    case KMSB_HASH_SHA256:
+        if(EVP_SUCCESS != EVP_DigestSignInit(mdctx, NULL, EVP_sha256(), NULL, pkey))
+            return KMSB_ERROR_OPERATION_FAILED;
+        break;
+    case KMSB_HASH_SHA384:
+        if(EVP_SUCCESS != EVP_DigestSignInit(mdctx, NULL, EVP_sha384(), NULL, pkey))
+            return KMSB_ERROR_OPERATION_FAILED;
+        break;
+    case KMSB_HASH_SHA512:
+        if(EVP_SUCCESS != EVP_DigestSignInit(mdctx, NULL, EVP_sha512(), NULL, pkey))
+            return KMSB_ERROR_OPERATION_FAILED;
+        break;
+    default:
+        return KMSB_ERROR_NOT_SUPPORTED;
+    }
+    /* Initialise the DigestSign operation - SHA-256 has been selected as the message digest function in this example */
+
+    /* Call update with the message */
+    if(EVP_SUCCESS != EVP_DigestSignUpdate(mdctx, msg, msg_len))
+        return KMSB_ERROR_OPERATION_FAILED;
+
+    /* Finalise the DigestSign operation */
+    /* First call EVP_DigestSignFinal with a NULL sig parameter to obtain the length of the
+    * signature. Length is returned in slen */
+    if(EVP_SUCCESS != EVP_DigestSignFinal(mdctx, NULL, sig_len))
+        return KMSB_ERROR_OPERATION_FAILED;
+    /* Allocate memory for the signature based on size in slen */
+    if(!(*sig = OPENSSL_malloc(sizeof(unsigned char) * (*sig_len))))
+        return KMSB_ERROR_OUT_OF_MEMORY;
+    /* Obtain the signature */
+    if(EVP_SUCCESS != EVP_DigestSignFinal(mdctx, *sig, sig_len))
+        return KMSB_ERROR_OPERATION_FAILED;
+
+    /* Clean up */
+    if(mdctx) EVP_MD_CTX_destroy(mdctx);
+    return KMSB_ERROR_NONE;
 }
 
-int kmsb_verify_signature(const unsigned int key_idx,
+kmsb_error_e kmsb_verify_signature(const unsigned int key_idx,
                 const kmsb_sign_param_s *param,
                 const unsigned char *msg, const unsigned int msg_len,
                 unsigned char *sig, unsigned int sig_len)
 {
-    // check the validate of key_idx
-    if (key_idx != ECDSA_KEY_IDX) return KMSB_ERROR_INVALID_PARAMETER;
+    kmsb_error_e ret = KMSB_ERROR_NONE;
     if (!KEY_ARRAY[key_idx]) {
-        if (KMSB_ERROR_NONE != generate_ecdsa_key(key_idx, false))
-            return KMSB_ERROR_NO_KEY;
+        ret = generate_ecdsa_key(key_idx, param->ec_type, false);
+        if (KMSB_ERROR_NONE != ret)
+            return ret;
     }
-    (void) param;
-    (void) msg;
-    (void) msg_len;
-    (void) sig;
-    (void) sig_len;
-    return KMSB_ERROR_NOT_SUPPORTED;
+
+    EVP_PKEY *pkey = (EVP_PKEY *)KEY_ARRAY[key_idx];
+    EVP_MD_CTX *mdctx = NULL;
+    /* Create the Message Digest Context */
+    if(!(mdctx = EVP_MD_CTX_create()))
+        return KMSB_ERROR_OPERATION_FAILED;
+
+    switch (param->hash_algo) {
+    case KMSB_HASH_SHA1:
+        if(EVP_SUCCESS != EVP_DigestVerifyInit(mdctx, NULL, EVP_sha1(), NULL, pkey))
+            return KMSB_ERROR_OPERATION_FAILED;
+        break;
+    case KMSB_HASH_SHA256:
+        if(EVP_SUCCESS != EVP_DigestVerifyInit(mdctx, NULL, EVP_sha256(), NULL, pkey))
+            return KMSB_ERROR_OPERATION_FAILED;
+        break;
+    case KMSB_HASH_SHA384:
+        if(EVP_SUCCESS != EVP_DigestVerifyInit(mdctx, NULL, EVP_sha384(), NULL, pkey))
+            return KMSB_ERROR_OPERATION_FAILED;
+        break;
+    case KMSB_HASH_SHA512:
+        if(EVP_SUCCESS != EVP_DigestVerifyInit(mdctx, NULL, EVP_sha512(), NULL, pkey))
+            return KMSB_ERROR_OPERATION_FAILED;
+        break;
+    default:
+        return KMSB_ERROR_NOT_SUPPORTED;
+    }
+    /* Initialize `key` with a public key */
+    if(EVP_SUCCESS != EVP_DigestVerifyUpdate(mdctx, msg, msg_len))
+        return KMSB_ERROR_OPERATION_FAILED;
+    if(EVP_SUCCESS != EVP_DigestVerifyFinal(mdctx, sig, sig_len))
+        return KMSB_ERROR_VERIFICATION_FAILED;
+
+    return KMSB_ERROR_NONE;
 }
 
 int kmsb_get_key(const unsigned int key_idx, unsigned char **output, unsigned int *output_len)
index 31ea8ef..3e3c0a0 100644 (file)
@@ -202,6 +202,10 @@ BOOST_AUTO_TEST_CASE(kmsb_encrypt_with_dbp_key_invalid_parameter_n)
 
 ///////////////////////////
 const int TEST_AES_KEY_IDX = 1;
+const int TEST_ECDSA_P192_KEY_IDX = 2;
+const int TEST_ECDSA_P256_KEY_IDX = 3;
+const int TEST_ECDSA_S384_KEY_IDX = 4;
+
 BOOST_AUTO_TEST_CASE(kmsb_aes_cbc_encrypt_p)
 {
     kmsb_error_e ret = KMSB_ERROR_NONE;
@@ -465,6 +469,222 @@ BOOST_AUTO_TEST_CASE(kmsb_aes_gcm_decrypt_p)
     if (output2) free(output2);
 }
 
+void test_kmsb_create_signature(int key_idx, 
+                                kmsb_hash_algo_e alg, kmsb_ec_type_e ec,
+                                unsigned char *input, unsigned int input_len,
+                                unsigned char **output, unsigned int *output_len)
+{
+    kmsb_error_e ret = KMSB_ERROR_NONE;
+    kmsb_sign_param_s param;
+    param.ec_type = ec;
+    param.hash_algo = alg;
+
+    ret = kmsb_create_signature(key_idx, &param,
+                            input, input_len,
+                            output, output_len);
+    BOOST_REQUIRE(ret == KMSB_ERROR_NONE);
+}
+
+void test_kmsb_verify_signature(int key_idx, 
+                                kmsb_hash_algo_e alg, kmsb_ec_type_e ec,
+                                unsigned char *input, unsigned int input_len,
+                                unsigned char **output, unsigned int *output_len)
+{
+    kmsb_error_e ret = KMSB_ERROR_NONE;
+    kmsb_sign_param_s param;
+    param.ec_type = ec;
+    param.hash_algo = alg;
+
+    ret = kmsb_create_signature(key_idx, &param,
+                            input, input_len,
+                            output, output_len);
+    BOOST_REQUIRE(ret == KMSB_ERROR_NONE);
+
+    ret = kmsb_verify_signature(key_idx, &param,
+                            input, input_len,
+                            *output, *output_len);
+    BOOST_REQUIRE(ret == KMSB_ERROR_NONE);
+}
+
+BOOST_AUTO_TEST_CASE(kmsb_create_signature_sha1_p)
+{
+    unsigned char input[32] = {0x01};
+    unsigned char *signature = NULL;
+    unsigned int signature_len = 0;
+
+    kmsb_hash_algo_e alg = KMSB_HASH_SHA1;
+    kmsb_ec_type_e ec = KMSB_EC_PRIME256V1;
+    test_kmsb_create_signature(TEST_ECDSA_P256_KEY_IDX, alg, ec,
+                            input, sizeof(input),
+                            &signature, &signature_len);
+
+    if (signature) free(signature);
+}
+
+BOOST_AUTO_TEST_CASE(kmsb_create_signature_sha256_p)
+{
+    unsigned char input[32] = {0x01};
+    unsigned char *signature = NULL;
+    unsigned int signature_len = 0;
+
+    kmsb_hash_algo_e alg = KMSB_HASH_SHA256;
+    kmsb_ec_type_e ec = KMSB_EC_PRIME256V1;
+    test_kmsb_create_signature(TEST_ECDSA_P256_KEY_IDX, alg, ec,
+                            input, sizeof(input),
+                            &signature, &signature_len);
+
+    if (signature) free(signature);
+}
+
+BOOST_AUTO_TEST_CASE(kmsb_create_signature_sha384_p)
+{
+    unsigned char input[32] = {0x01};
+    unsigned char *signature = NULL;
+    unsigned int signature_len = 0;
+
+    kmsb_hash_algo_e alg = KMSB_HASH_SHA384;
+    kmsb_ec_type_e ec = KMSB_EC_PRIME256V1;
+    test_kmsb_create_signature(TEST_ECDSA_P256_KEY_IDX, alg, ec,
+                            input, sizeof(input),
+                            &signature, &signature_len);
+
+    if (signature) free(signature);
+}
+
+BOOST_AUTO_TEST_CASE(kmsb_create_signature_sha512_p)
+{
+    unsigned char input[32] = {0x01};
+    unsigned char *signature = NULL;
+    unsigned int signature_len = 0;
+
+    kmsb_hash_algo_e alg = KMSB_HASH_SHA512;
+    kmsb_ec_type_e ec = KMSB_EC_PRIME256V1;
+    test_kmsb_create_signature(TEST_ECDSA_P256_KEY_IDX, alg, ec,
+                            input, sizeof(input),
+                            &signature, &signature_len);
+
+    if (signature) free(signature);
+}
+
+BOOST_AUTO_TEST_CASE(kmsb_create_signature_p192v1_p)
+{
+    unsigned char input[32] = {0x01};
+    unsigned char *signature = NULL;
+    unsigned int signature_len = 0;
+
+    kmsb_hash_algo_e alg = KMSB_HASH_SHA256;
+    kmsb_ec_type_e ec = KMSB_EC_PRIME192V1;
+    test_kmsb_create_signature(TEST_ECDSA_P192_KEY_IDX, alg, ec,
+                            input, sizeof(input),
+                            &signature, &signature_len);
+
+    if (signature) free(signature);
+}
+
+BOOST_AUTO_TEST_CASE(kmsb_create_signature_secp384r1_p)
+{
+    unsigned char input[32] = {0x01};
+    unsigned char *signature = NULL;
+    unsigned int signature_len = 0;
+
+    kmsb_hash_algo_e alg = KMSB_HASH_SHA256;
+    kmsb_ec_type_e ec = KMSB_EC_SECP384R1;
+    test_kmsb_create_signature(TEST_ECDSA_S384_KEY_IDX, alg, ec,
+                            input, sizeof(input),
+                            &signature, &signature_len);
+
+    if (signature) free(signature);
+}
+
+BOOST_AUTO_TEST_CASE(kmsb_verify_signature_sha1_p)
+{
+    unsigned char input[32] = {0x01};
+    unsigned char *signature = NULL;
+    unsigned int signature_len = 0;
+
+    kmsb_hash_algo_e alg = KMSB_HASH_SHA1;
+    kmsb_ec_type_e ec = KMSB_EC_PRIME256V1;
+    test_kmsb_verify_signature(TEST_ECDSA_P256_KEY_IDX, alg, ec,
+                            input, sizeof(input),
+                            &signature, &signature_len);
+
+    if (signature) free(signature);
+}
+
+BOOST_AUTO_TEST_CASE(kmsb_verify_signature_sha256_p)
+{
+    unsigned char input[32] = {0x01};
+    unsigned char *signature = NULL;
+    unsigned int signature_len = 0;
+
+    kmsb_hash_algo_e alg = KMSB_HASH_SHA256;
+    kmsb_ec_type_e ec = KMSB_EC_PRIME256V1;
+    test_kmsb_verify_signature(TEST_ECDSA_P256_KEY_IDX, alg, ec,
+                            input, sizeof(input),
+                            &signature, &signature_len);
+
+    if (signature) free(signature);
+}
+
+BOOST_AUTO_TEST_CASE(kmsb_verify_signature_sha384_p)
+{
+    unsigned char input[32] = {0x01};
+    unsigned char *signature = NULL;
+    unsigned int signature_len = 0;
+
+    kmsb_hash_algo_e alg = KMSB_HASH_SHA384;
+    kmsb_ec_type_e ec = KMSB_EC_PRIME256V1;
+    test_kmsb_verify_signature(TEST_ECDSA_P256_KEY_IDX, alg, ec,
+                            input, sizeof(input),
+                            &signature, &signature_len);
+
+    if (signature) free(signature);
+}
+
+BOOST_AUTO_TEST_CASE(kmsb_verify_signature_sha512_p)
+{
+    unsigned char input[32] = {0x01};
+    unsigned char *signature = NULL;
+    unsigned int signature_len = 0;
+
+    kmsb_hash_algo_e alg = KMSB_HASH_SHA512;
+    kmsb_ec_type_e ec = KMSB_EC_PRIME256V1;
+    test_kmsb_verify_signature(TEST_ECDSA_P256_KEY_IDX, alg, ec,
+                            input, sizeof(input),
+                            &signature, &signature_len);
+
+    if (signature) free(signature);
+}
+
+BOOST_AUTO_TEST_CASE(kmsb_verify_signature_p192v1_p)
+{
+    unsigned char input[32] = {0x01};
+    unsigned char *signature = NULL;
+    unsigned int signature_len = 0;
+
+    kmsb_hash_algo_e alg = KMSB_HASH_SHA256;
+    kmsb_ec_type_e ec = KMSB_EC_PRIME192V1;
+    test_kmsb_verify_signature(TEST_ECDSA_P192_KEY_IDX, alg, ec,
+                            input, sizeof(input),
+                            &signature, &signature_len);
+
+    if (signature) free(signature);
+}
+
+BOOST_AUTO_TEST_CASE(kmsb_verify_signature_secp384r1_p)
+{
+    unsigned char input[32] = {0x01};
+    unsigned char *signature = NULL;
+    unsigned int signature_len = 0;
+
+    kmsb_hash_algo_e alg = KMSB_HASH_SHA256;
+    kmsb_ec_type_e ec = KMSB_EC_SECP384R1;
+    test_kmsb_verify_signature(TEST_ECDSA_S384_KEY_IDX, alg, ec,
+                            input, sizeof(input),
+                            &signature, &signature_len);
+
+    if (signature) free(signature);
+}
 BOOST_AUTO_TEST_SUITE_END() // SE_EMUL
 
 BOOST_AUTO_TEST_SUITE_END() // USER