* 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
* 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
#include <string.h>
#include <stdbool.h>
#include <openssl/aes.h>
+#include <openssl/ec.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
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
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;
if(buf) free(buf); \
return result; \
}
-
#define FREE_OUT(buf, result) \
{ \
if(buf) free(buf); \
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;
}
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)
///////////////////////////
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;
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, ¶m,
+ 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, ¶m,
+ input, input_len,
+ output, output_len);
+ BOOST_REQUIRE(ret == KMSB_ERROR_NONE);
+
+ ret = kmsb_verify_signature(key_idx, ¶m,
+ 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