2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
17 * @file km_se_backend.c
18 * @author Dongsun Lee (ds73.lee@samsung.com)
20 * @brief provides fucntions for SE Backedn for Key Manager
23 //################################################################################
25 // This is a dummy implementation of SE backend to show how to implement SE backend.
26 // Do not use this dummpy implementation in commodity devices.
27 //################################################################################
32 #include <openssl/aes.h>
33 #include <openssl/ec.h>
34 #include <openssl/evp.h>
35 #include <openssl/rand.h>
37 #include "key-manager-se-backend.h"
39 //################################################################################
40 // Global variables and defines
41 //################################################################################
50 #define MAX_SLOT_INDEX 8
52 static unsigned char *KEY_ARRAY[MAX_SLOT_INDEX] = {NULL,};
53 static unsigned char CERT_ARRAY[MAX_SLOT_INDEX][1244] =
54 {"MIIDnzCCAoegAwIBAgIJAMH/ADkC5YSTMA0GCSqGSIb3DQEBBQUAMGYxCzAJBgNVBAYTAkFVMRMw" \
55 "EQYDVQQIDApTb21lLVN0YXRlMQ0wCwYDVQQKDARBQ01FMRAwDgYDVQQLDAdUZXN0aW5nMSEwHwYD" \
56 "VQQDDBhUZXN0IHJvb3QgY2EgY2VydGlmaWNhdGUwHhcNMTQxMjMwMTcyMTUyWhcNMjQxMjI3MTcy" \
57 "MTUyWjBmMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTENMAsGA1UECgwEQUNNRTEQ" \
58 "MA4GA1UECwwHVGVzdGluZzEhMB8GA1UEAwwYVGVzdCByb290IGNhIGNlcnRpZmljYXRlMIIBIjAN" \
59 "BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0EJRdUtd2th0vTVF7QxvDKzyFCF3w9vC9IDE/Yr1" \
60 "2w+a9jd0s7/eG96qTHIYffS3B7x2MB+d4n+SR3W0qmYh7xk8qfEgH3daeDoV59IZ9r543KM+g8jm" \
61 "6KffYGX1bIJVVY5OhBRbO9nY6byYpd5kbCIUB6dCf7/WrQl1aIdLGFIegAzPGFPXDcU6F192686x" \
62 "54bxt/itMX4agHJ9ZC/rrTBIZghVsjJo5/AH5WZpasv8sfrGiiohAxtieoYoJkv5MOYP4/2lPlOY" \
63 "+Cgw1Yoz+HHv31AllgFsBquBb/kJVmCCNsAOcnvQzTZUsW/TXz9G2nwRdqI1nSy2JvVjZGsqGQID" \
64 "AQABo1AwTjAdBgNVHQ4EFgQUt6pkzFt1PZlfYRL/HGnufF4frdwwHwYDVR0jBBgwFoAUt6pkzFt1" \
65 "PZlfYRL/HGnufF4frdwwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAld7Qwq0cdzDQ" \
66 "51w1RVLwTR8Oy25PB3rzwEHcSGJmdqlMi3xOdaz80S1R1BBXldvGBG5Tn0vT7xSuhmSgI2/HnBpy" \
67 "9ocHVOmhtNB4473NieEpfTYrnGXrFxu46Wus9m/ZnugcQ2G6C54A/NFtvgLmaC8uH8M7gKdS6uYU" \
68 "wJFQEofkjmd4UpOYSqmcRXhSJzd5FYFWkJhKJYp3nlENSOD8CUFFVGekm05nFN2gRVc/qaqQkEX7" \
69 "7+XYvhodLRsVqMn7nf7taidDKLO2T4bhujztnTYOhhaXKgPy7AtZ28N2wvX96VyAPB/vrchGmyBK" \
70 "kOg11TpPdNDkhb1J4ZCh2gupDg==",};
71 static unsigned char DATA_ARRAY[MAX_SLOT_INDEX][1000] =
74 const size_t DBP_KEY_SIZE = 32;
75 const size_t AES_KEY_SIZE = 32;
76 const size_t BLOCK_SIZE = 16;
77 const int32_t OPENSSL_SUCCESS = 1;
79 #define FREE_OUT_CTX(ctx, buf, result) \
81 EVP_CIPHER_CTX_free(ctx); \
85 #define FREE_OUT(buf, result) \
91 //################################################################################
92 // For Supporting Key Manager DB Encryption with SE Key
93 //################################################################################
94 kmsb_error_e kmsb_generate_dbp_key(const bool delete_old)
96 if (!delete_old && KEY_ARRAY[DBP_KEY_IDX])
97 return KMSB_ERROR_NOT_PERMITTED;
99 if (!KEY_ARRAY[DBP_KEY_IDX]) {
100 KEY_ARRAY[DBP_KEY_IDX] = calloc(DBP_KEY_SIZE, sizeof(unsigned char));
102 memset(KEY_ARRAY[DBP_KEY_IDX], 0, DBP_KEY_SIZE);
105 // if (1 != RAND_bytes(KEY_ARRAY[DBP_KEY_IDX], DBP_KEY_SIZE))
106 // FREE_OUT(KEY_ARRAY[DBP_KEY_IDX], KMSB_ERROR_OPERATION_FAILED)
107 memset(KEY_ARRAY[DBP_KEY_IDX], 01, DBP_KEY_SIZE);
109 return KMSB_ERROR_NONE;
112 kmsb_error_e kmsb_encrypt_with_dbp_key(const int dbp_scheme,
113 const unsigned char *input, const unsigned int input_len,
114 const unsigned char *iv, const unsigned int iv_len,
115 unsigned char **output, unsigned int *output_len)
117 unsigned int aes_block_size = 16;
118 if (dbp_scheme != (const int) SE_BACKEND_DBP_SCHEME_VERSION)
119 return KMSB_ERROR_INVALID_PARAMETER;
120 if (!KEY_ARRAY[DBP_KEY_IDX])
121 return KMSB_ERROR_NO_KEY;
123 input_len == 0 || input_len % aes_block_size != 0 ||
125 iv_len != aes_block_size ||
128 return KMSB_ERROR_INVALID_PARAMETER;
131 AES_set_encrypt_key(KEY_ARRAY[DBP_KEY_IDX], DBP_KEY_SIZE*8, &aes_key);
133 *output = malloc(input_len);
135 return KMSB_ERROR_OUT_OF_MEMORY;
136 *output_len = input_len;
138 unsigned char *iv_temp = malloc(iv_len);
140 return KMSB_ERROR_OUT_OF_MEMORY;
141 memcpy(iv_temp, iv, iv_len);
143 AES_cbc_encrypt(input,
150 return KMSB_ERROR_NONE;
153 //################################################################################
154 // For Supporting Preloaded SE Data
155 //################################################################################
156 static kmsb_error_e generate_aes_key(const unsigned int key_idx,
157 const bool delete_old)
159 if (!delete_old && KEY_ARRAY[key_idx])
160 return KMSB_ERROR_NOT_PERMITTED;
162 if (!KEY_ARRAY[key_idx]) {
163 KEY_ARRAY[key_idx] = calloc(AES_KEY_SIZE, sizeof(unsigned char));
165 memset(KEY_ARRAY[key_idx], 0, AES_KEY_SIZE);
168 if (1 != RAND_bytes(KEY_ARRAY[key_idx], AES_KEY_SIZE))
169 FREE_OUT(KEY_ARRAY[key_idx], KMSB_ERROR_OPERATION_FAILED)
171 return KMSB_ERROR_NONE;
174 static kmsb_error_e generate_ecdsa_key(const unsigned int key_idx,
175 kmsb_ec_type_e ec, const bool delete_old)
177 if (!delete_old && KEY_ARRAY[key_idx])
178 return KMSB_ERROR_NOT_PERMITTED;
180 /* Create the context for generating the parameters */
181 EVP_PKEY_CTX *pctx = NULL;
182 EVP_PKEY *pkey = NULL;
183 if (!(pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL)))
184 return KMSB_ERROR_OPERATION_FAILED;
185 if (!EVP_PKEY_paramgen_init(pctx))
186 return KMSB_ERROR_OPERATION_FAILED;
191 case KMSB_EC_PRIME192V1:
192 nid = NID_X9_62_prime192v1;
193 idx = EC_P192_KEY_IDX;
195 case KMSB_EC_PRIME256V1:
196 nid = NID_X9_62_prime256v1;
197 idx = EC_P256_KEY_IDX;
199 case KMSB_EC_SECP384R1:
201 idx = EC_S384_KEY_IDX;
204 return KMSB_ERROR_NOT_SUPPORTED;
207 return KMSB_ERROR_INVALID_PARAMETER;
209 /* Use the NID_X9_62_prime256v1 named curve - defined in obj_mac.h */
210 if (!EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, nid))
211 return KMSB_ERROR_OPERATION_FAILED;
213 if (!EVP_PKEY_keygen_init(pctx))
214 return KMSB_ERROR_OPERATION_FAILED;
215 /* Generate the key */
216 if (!EVP_PKEY_keygen(pctx, &pkey))
217 return KMSB_ERROR_OPERATION_FAILED;
219 return KMSB_ERROR_OPERATION_FAILED;
221 KEY_ARRAY[key_idx] = (unsigned char*)pkey;
222 return KMSB_ERROR_NONE;
225 static kmsb_error_e aes_gcm_encrypt(EVP_CIPHER_CTX *ctx, kmsb_aes_param_s *param, uint8_t *key,
226 const unsigned char *input, const unsigned int input_len,
227 unsigned char **output, unsigned int *output_len)
229 int clen = 0, flen = 0;
230 unsigned char* buf = NULL;
232 /* Initialise the encryption operation. */
233 if (OPENSSL_SUCCESS != EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL))
234 return KMSB_ERROR_OPERATION_FAILED;
236 * Set IV length if default 12 bytes (96 bits) is not appropriate
238 if (OPENSSL_SUCCESS != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, param->iv_len, NULL))
239 return KMSB_ERROR_OPERATION_FAILED;
241 /* Initialise key and IV */
242 if (OPENSSL_SUCCESS != EVP_EncryptInit_ex(ctx, NULL, NULL, key, param->iv))
243 return KMSB_ERROR_OPERATION_FAILED;
245 clen = input_len + EVP_CIPHER_CTX_block_size(ctx);
246 buf = calloc(clen, sizeof(unsigned char));
247 if (!buf) return KMSB_ERROR_OUT_OF_MEMORY;
250 * Set Padding zero forcely, with our concept, there should be no padding
251 * to increase buffer size.
253 if (OPENSSL_SUCCESS != EVP_CIPHER_CTX_set_padding(ctx, 0))
254 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
256 * Provide any AAD data. This can be called zero or more times as
259 if (OPENSSL_SUCCESS != EVP_EncryptUpdate(ctx, NULL, &clen, param->aad, param->aad_len))
260 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
262 * Provide the message to be encrypted, and obtain the encrypted output.
263 * EVP_EncryptUpdate can be called multiple times if necessary
265 if (OPENSSL_SUCCESS != EVP_EncryptUpdate(ctx, buf, &clen, input, input_len))
266 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
268 * Finalise the encryption. Normally ciphertext bytes may be written at
269 * this stage, but this does not occur in GCM mode
271 if (OPENSSL_SUCCESS != EVP_EncryptFinal_ex(ctx, buf + clen, &flen))
272 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
273 *output_len = clen + flen;
276 if (OPENSSL_SUCCESS != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, param->tag))
277 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
279 *output = calloc(*output_len, sizeof(unsigned char));
281 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OUT_OF_MEMORY)
282 memcpy(*output, buf, *output_len);
284 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_NONE)
287 static kmsb_error_e aes_gcm_decrypt(EVP_CIPHER_CTX *ctx, kmsb_aes_param_s *param, uint8_t *key,
288 const unsigned char *input, const unsigned int input_len,
289 unsigned char **output, unsigned int *output_len)
291 int clen = 0, flen = 0;
292 unsigned char* buf = NULL;
294 /* Initialise the decryption operation. */
295 if (OPENSSL_SUCCESS != EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL))
296 return KMSB_ERROR_OPERATION_FAILED;
298 * Set IV length if default 12 bytes (96 bits) is not appropriate
300 if (OPENSSL_SUCCESS != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, param->iv_len, NULL))
301 return KMSB_ERROR_OPERATION_FAILED;
302 /* Initialise key and IV */
303 if (OPENSSL_SUCCESS != EVP_DecryptInit_ex(ctx, NULL, NULL, key, param->iv))
304 return KMSB_ERROR_OPERATION_FAILED;
305 clen = input_len + EVP_CIPHER_CTX_block_size(ctx);
306 buf = calloc(clen, sizeof(unsigned char));
307 if (!buf) return KMSB_ERROR_OUT_OF_MEMORY;
309 * Set Padding zero forcely, with our concept, there should be no padding
310 * to increase buffer size.
312 if (OPENSSL_SUCCESS != EVP_CIPHER_CTX_set_padding(ctx, 0))
313 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
315 * Provide any AAD data. This can be called zero or more times as
318 if (OPENSSL_SUCCESS != EVP_DecryptUpdate(ctx, NULL, &clen, param->aad, param->aad_len))
319 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
321 * Provide the message to be decrypted, and obtain the plaintext output.
322 * EVP_DecryptUpdate can be called multiple times if necessary
324 if (OPENSSL_SUCCESS != EVP_DecryptUpdate(ctx, buf, &clen, input, input_len))
325 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
326 /* Set expected tag value. Works in OpenSSL 1.0.1d and later */
327 if (OPENSSL_SUCCESS != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, param->tag))
328 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
330 * Finalise the decryption. A positive return value indicates success,
331 * anything else is a failure - the plaintext is not trustworthy.
333 if (OPENSSL_SUCCESS != EVP_DecryptFinal_ex(ctx, buf + clen, &flen))
334 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
335 *output_len = clen + flen;
337 *output = calloc(*output_len, sizeof(unsigned char));
339 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OUT_OF_MEMORY)
340 memcpy(*output, buf, *output_len);
342 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_NONE)
345 kmsb_error_e kmsb_aes_encrypt(const unsigned int key_idx,
346 kmsb_aes_param_s *param,
347 const unsigned char *input, const unsigned int input_len,
348 unsigned char **output, unsigned int *output_len)
350 // check the input parameters
351 if (key_idx >= MAX_SLOT_INDEX ||
355 output_len == NULL ||
358 return KMSB_ERROR_INVALID_PARAMETER;
360 // check the validate of key_idx
361 if (key_idx != AES_KEY_IDX) return KMSB_ERROR_INVALID_PARAMETER;
362 if (!KEY_ARRAY[key_idx]) {
363 if (KMSB_ERROR_NONE != generate_aes_key(key_idx, false))
364 return KMSB_ERROR_NO_KEY;
368 int clen = 0, flen = 0;
369 unsigned char* buf = NULL;
370 unsigned char* key = KEY_ARRAY[key_idx];
371 EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
372 switch (param->mode) {
373 case KMSB_ALGO_AES_CTR:
374 ret = EVP_EncryptInit_ex(ctx, EVP_aes_256_ctr(), NULL, key, param->iv);
376 case KMSB_ALGO_AES_CBC:
377 ret = EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, param->iv);
379 case KMSB_ALGO_AES_GCM:
380 return aes_gcm_encrypt(ctx, param, key, input, input_len, output, output_len);
381 case KMSB_ALGO_AES_CFB:
382 ret = EVP_EncryptInit_ex(ctx, EVP_aes_256_cfb8(), NULL, key, param->iv);
385 return KMSB_ERROR_NOT_SUPPORTED;
387 if (OPENSSL_SUCCESS != ret) return KMSB_ERROR_OPERATION_FAILED;
389 clen = input_len + EVP_CIPHER_CTX_block_size(ctx);
390 buf = calloc(clen, sizeof(unsigned char));
391 if (!buf) return KMSB_ERROR_OUT_OF_MEMORY;
394 * Set Padding zero forcely, with our concept, there should be no padding
395 * to increase buffer size.
397 if (OPENSSL_SUCCESS != EVP_CIPHER_CTX_set_padding(ctx, 0))
398 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
400 * Provide the message to be encrypted, and obtain the encrypted output.
401 * EVP_EncryptUpdate can be called multiple times if necessary
403 if (OPENSSL_SUCCESS != EVP_EncryptUpdate(ctx, buf, &clen, input, input_len))
404 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
406 * Finalise the encryption. Further ciphertext bytes may be written at
409 if (OPENSSL_SUCCESS != EVP_EncryptFinal_ex(ctx, buf + clen, &flen))
410 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
411 *output_len = clen + flen;
413 *output = calloc(*output_len, sizeof(unsigned char));
415 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OUT_OF_MEMORY)
416 memcpy(*output, buf, *output_len);
418 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_NONE)
421 kmsb_error_e kmsb_aes_decrypt(const unsigned int key_idx,
422 kmsb_aes_param_s *param,
423 const unsigned char *input, const unsigned int input_len,
424 unsigned char **output, unsigned int *output_len)
426 // check the input parameters
427 if (key_idx >= MAX_SLOT_INDEX ||
431 output_len == NULL ||
434 return KMSB_ERROR_INVALID_PARAMETER;
436 // check the validate of key_idx
437 if (key_idx != AES_KEY_IDX) return KMSB_ERROR_INVALID_PARAMETER;
438 if (!KEY_ARRAY[key_idx]) {
439 if (KMSB_ERROR_NONE != generate_aes_key(key_idx, false))
440 return KMSB_ERROR_NO_KEY;
444 int clen = 0, flen = 0;
445 unsigned char* buf = NULL;
446 unsigned char* key = KEY_ARRAY[key_idx];
447 EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
449 switch (param->mode) {
450 case KMSB_ALGO_AES_CTR:
451 ret = EVP_DecryptInit_ex(ctx, EVP_aes_256_ctr(), NULL, key, param->iv);
453 case KMSB_ALGO_AES_CBC:
454 ret = EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, param->iv);
456 case KMSB_ALGO_AES_GCM:
457 return aes_gcm_decrypt(ctx, param, key, input, input_len, output, output_len);
458 case KMSB_ALGO_AES_CFB:
459 ret = EVP_DecryptInit_ex(ctx, EVP_aes_256_cfb8(), NULL, key, param->iv);
462 return KMSB_ERROR_NOT_SUPPORTED;
464 if (OPENSSL_SUCCESS != ret) return KMSB_ERROR_OPERATION_FAILED;
466 clen = input_len + EVP_CIPHER_CTX_block_size(ctx);
467 buf = calloc(clen, sizeof(unsigned char));
468 if (!buf) return KMSB_ERROR_OUT_OF_MEMORY;
471 * Set Padding zero forcely, with our concept, there should be no padding
472 * to increase buffer size.
474 if (OPENSSL_SUCCESS != EVP_CIPHER_CTX_set_padding(ctx, 0))
475 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
477 * Provide the message to be decrypted, and obtain the plaintext output.
478 * EVP_DecryptUpdate can be called multiple times if necessary
480 if (OPENSSL_SUCCESS != EVP_DecryptUpdate(ctx, buf, &clen, input, input_len))
481 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
483 * Finalise the decryption. Further plaintext bytes may be written at
486 if (OPENSSL_SUCCESS != EVP_DecryptFinal_ex(ctx, buf + clen, &flen))
487 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
488 *output_len = clen + flen;
490 *output = calloc(*output_len, sizeof(unsigned char));
492 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OUT_OF_MEMORY)
494 memcpy(*output, buf, *output_len);
495 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_NONE)
498 const EVP_MD *getMdAlgo(kmsb_hash_algo_e hash)
503 case KMSB_HASH_SHA256:
505 case KMSB_HASH_SHA384:
507 case KMSB_HASH_SHA512:
514 kmsb_error_e kmsb_create_signature(const unsigned int key_idx,
515 const kmsb_sign_param_s *param,
516 const unsigned char *msg, const unsigned int msg_len,
517 unsigned char **sig, unsigned int *sig_len)
519 // check the input parameters
520 if (key_idx >= MAX_SLOT_INDEX ||
525 return KMSB_ERROR_INVALID_PARAMETER;
527 kmsb_error_e ret = KMSB_ERROR_NONE;
528 if (!KEY_ARRAY[key_idx]) {
529 ret = generate_ecdsa_key(key_idx, param->ec_type, false);
530 if (KMSB_ERROR_NONE != ret)
534 EVP_PKEY *pkey = (EVP_PKEY *)KEY_ARRAY[key_idx];
535 EVP_MD_CTX *mdctx = NULL;
536 /* Create the Message Digest Context */
537 if (!(mdctx = EVP_MD_CTX_create()))
538 return KMSB_ERROR_OPERATION_FAILED;
540 const EVP_MD* hash = getMdAlgo(param->hash_algo);
541 if (hash == NULL) return KMSB_ERROR_NOT_SUPPORTED;
543 /* Initialise the DigestSign operation - SHA-256 has been selected as the message digest function in this example */
544 if (OPENSSL_SUCCESS != EVP_DigestSignInit(mdctx, NULL, hash, NULL, pkey))
545 return KMSB_ERROR_OPERATION_FAILED;
547 /* Call update with the message */
548 if (OPENSSL_SUCCESS != EVP_DigestSignUpdate(mdctx, msg, msg_len))
549 return KMSB_ERROR_OPERATION_FAILED;
551 /* Finalise the DigestSign operation */
552 /* First call EVP_DigestSignFinal with a NULL sig parameter to obtain the length of the
553 * signature. Length is returned in slen */
554 if (OPENSSL_SUCCESS != EVP_DigestSignFinal(mdctx, NULL, sig_len))
555 return KMSB_ERROR_OPERATION_FAILED;
556 /* Allocate memory for the signature based on size in slen */
557 if (!(*sig = OPENSSL_malloc(sizeof(unsigned char) * (*sig_len))))
558 return KMSB_ERROR_OUT_OF_MEMORY;
559 /* Obtain the signature */
560 if (OPENSSL_SUCCESS != EVP_DigestSignFinal(mdctx, *sig, sig_len))
561 return KMSB_ERROR_OPERATION_FAILED;
564 if (mdctx) EVP_MD_CTX_destroy(mdctx);
565 return KMSB_ERROR_NONE;
568 kmsb_error_e kmsb_verify_signature(const unsigned int key_idx,
569 const kmsb_sign_param_s *param,
570 const unsigned char *msg, const unsigned int msg_len,
571 const unsigned char *sig, const unsigned int sig_len)
573 // check the input parameters
574 if (key_idx >= MAX_SLOT_INDEX ||
579 return KMSB_ERROR_INVALID_PARAMETER;
581 kmsb_error_e ret = KMSB_ERROR_NONE;
582 if (!KEY_ARRAY[key_idx]) {
583 ret = generate_ecdsa_key(key_idx, param->ec_type, false);
584 if (KMSB_ERROR_NONE != ret)
588 EVP_PKEY *pkey = (EVP_PKEY *)KEY_ARRAY[key_idx];
589 EVP_MD_CTX *mdctx = NULL;
590 /* Create the Message Digest Context */
591 if (!(mdctx = EVP_MD_CTX_create()))
592 return KMSB_ERROR_OPERATION_FAILED;
594 const EVP_MD* hash = getMdAlgo(param->hash_algo);
595 if (hash == NULL) return KMSB_ERROR_NOT_SUPPORTED;
597 if (OPENSSL_SUCCESS != EVP_DigestVerifyInit(mdctx, NULL, hash, NULL, pkey))
598 return KMSB_ERROR_OPERATION_FAILED;
600 /* Initialize `key` with a public key */
601 if (OPENSSL_SUCCESS != EVP_DigestVerifyUpdate(mdctx, msg, msg_len))
602 return KMSB_ERROR_OPERATION_FAILED;
603 if (OPENSSL_SUCCESS != EVP_DigestVerifyFinal(mdctx, sig, sig_len))
604 return KMSB_ERROR_VERIFICATION_FAILED;
606 return KMSB_ERROR_NONE;
609 kmsb_error_e kmsb_get_key(const unsigned int key_idx, unsigned char **output, unsigned int *output_len)
611 if (key_idx >= MAX_SLOT_INDEX ||
614 return KMSB_ERROR_INVALID_PARAMETER;
616 if (!KEY_ARRAY[key_idx])
617 return KMSB_ERROR_NO_KEY;
619 EVP_PKEY *pkey = (EVP_PKEY *)KEY_ARRAY[key_idx];
621 EC_KEY *ec_key = EVP_PKEY_get1_EC_KEY(pkey);
623 return KMSB_ERROR_OPERATION_FAILED;
625 *output_len = EC_POINT_point2buf(EC_KEY_get0_group(ec_key),
626 EC_KEY_get0_public_key(ec_key),
629 return KMSB_ERROR_OPERATION_FAILED;
631 return KMSB_ERROR_NONE;
634 /* warn: The cerification data should be pre-loaded in Secure element */
635 kmsb_error_e kmsb_get_certificate(const unsigned int cert_idx, unsigned char **output, unsigned int *output_len)
637 if (cert_idx >= MAX_SLOT_INDEX ||
640 return KMSB_ERROR_INVALID_PARAMETER;
642 if (!CERT_ARRAY[cert_idx])
643 return KMSB_ERROR_OPERATION_FAILED;
645 *output_len = strlen((const char*)CERT_ARRAY[cert_idx]);
646 *output = calloc(*output_len, sizeof(unsigned char));
647 if (!*output) return KMSB_ERROR_OUT_OF_MEMORY;
649 memcpy(*output, CERT_ARRAY[cert_idx], *output_len);
650 return KMSB_ERROR_NONE;
653 /* warn: The data should be pre-loaded securely in Secure element */
654 kmsb_error_e kmsb_get_data(const unsigned int data_idx, unsigned char **output, unsigned int *output_len)
656 if (data_idx >= MAX_SLOT_INDEX ||
659 return KMSB_ERROR_INVALID_PARAMETER;
661 if (!DATA_ARRAY[data_idx])
662 return KMSB_ERROR_OPERATION_FAILED;
664 *output_len = strlen((const char*)DATA_ARRAY[data_idx]);
665 *output = calloc(*output_len, sizeof(unsigned char));
666 if (!*output) return KMSB_ERROR_OUT_OF_MEMORY;
668 memcpy(*output, DATA_ARRAY[data_idx], *output_len);
669 return KMSB_ERROR_NONE;