complement negative test cases
[platform/core/security/key-manager-se-backend.git] / srcs / km_se_backend.c
1 /*
2  *  Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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
15  *
16  *
17  * @file        km_se_backend.c
18  * @author      Dongsun Lee (ds73.lee@samsung.com)
19  * @version     1.0
20  * @brief       provides fucntions for SE Backedn for Key Manager
21  */
22
23 //################################################################################
24 // WARNING
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 //################################################################################
28
29 #include <stdlib.h>
30 #include <string.h>
31 #include <stdbool.h>
32 #include <openssl/aes.h>
33 #include <openssl/ec.h>
34 #include <openssl/evp.h>
35 #include <openssl/rand.h>
36
37 #include "key-manager-se-backend.h"
38
39 //################################################################################
40 // Global variables and defines
41 //################################################################################
42 enum {
43     DBP_KEY_IDX = 0,
44     AES_KEY_IDX,
45     EC_P192_KEY_IDX,
46     EC_P256_KEY_IDX,
47     EC_S384_KEY_IDX,
48 } KEY_INDEX;
49
50 #define MAX_SLOT_INDEX  8
51
52 static unsigned char *KEY_ARRAY[MAX_SLOT_INDEX] = {NULL,};
53
54 const size_t DBP_KEY_SIZE = 32;
55 const size_t AES_KEY_SIZE = 32;
56 const size_t BLOCK_SIZE = 16;
57 const int32_t OPENSSL_SUCCESS = 1;
58
59 #define FREE_OUT_CTX(ctx, buf, result) \
60     { \
61     EVP_CIPHER_CTX_free(ctx); \
62     if (buf) free(buf); \
63     return result; \
64     }
65 #define FREE_OUT(buf, result) \
66     { \
67     if (buf) free(buf); \
68     return result; \
69     }
70 //################################################################################
71 // For Supporting Key Manager DB Encryption with SE Key
72 //################################################################################
73 kmsb_error_e kmsb_generate_dbp_key(const bool delete_old)
74 {
75     if (!delete_old && KEY_ARRAY[DBP_KEY_IDX])
76         return KMSB_ERROR_NOT_PERMITTED;
77
78     if (!KEY_ARRAY[DBP_KEY_IDX]) {
79         KEY_ARRAY[DBP_KEY_IDX] = calloc(DBP_KEY_SIZE, sizeof(unsigned char));
80     } else {
81         memset(KEY_ARRAY[DBP_KEY_IDX], 0, DBP_KEY_SIZE);
82     }
83
84     // if (1 != RAND_bytes(KEY_ARRAY[DBP_KEY_IDX], DBP_KEY_SIZE))
85     //     FREE_OUT(KEY_ARRAY[DBP_KEY_IDX], KMSB_ERROR_OPERATION_FAILED)
86     memset(KEY_ARRAY[DBP_KEY_IDX], 01, DBP_KEY_SIZE);
87
88     return KMSB_ERROR_NONE;
89 }
90
91 kmsb_error_e kmsb_encrypt_with_dbp_key(const int dbp_scheme,
92     const unsigned char *input, const unsigned int input_len,
93     const unsigned char *iv, const unsigned int iv_len,
94     unsigned char **output, unsigned int *output_len)
95 {
96     unsigned int aes_block_size = 16;
97     if (dbp_scheme != (const int) SE_BACKEND_DBP_SCHEME_VERSION)
98         return KMSB_ERROR_INVALID_PARAMETER;
99     if (!KEY_ARRAY[DBP_KEY_IDX])
100         return KMSB_ERROR_NO_KEY;
101     if (input == NULL ||
102         input_len == 0 || input_len % aes_block_size != 0 ||
103         iv == NULL ||
104         iv_len != aes_block_size ||
105         output == NULL ||
106         output_len == NULL)
107         return KMSB_ERROR_INVALID_PARAMETER;
108
109     AES_KEY aes_key;
110     AES_set_encrypt_key(KEY_ARRAY[DBP_KEY_IDX], DBP_KEY_SIZE*8, &aes_key);
111
112     *output = malloc(input_len);
113     if (output == NULL)
114         return KMSB_ERROR_OUT_OF_MEMORY;
115     *output_len = input_len;
116
117     unsigned char *iv_temp = malloc(iv_len);
118     if (iv_temp == NULL)
119         return KMSB_ERROR_OUT_OF_MEMORY;
120     memcpy(iv_temp, iv, iv_len);
121
122     AES_cbc_encrypt(input,
123                     *output,
124                     input_len,
125                     &aes_key,
126                     iv_temp,
127                     AES_ENCRYPT);
128
129     return KMSB_ERROR_NONE;
130 }
131
132 //################################################################################
133 // For Supporting Preloaded SE Data
134 //################################################################################
135 static kmsb_error_e generate_aes_key(const unsigned int key_idx,
136                                         const bool delete_old)
137 {
138     if (!delete_old && KEY_ARRAY[key_idx])
139         return KMSB_ERROR_NOT_PERMITTED;
140
141     if (!KEY_ARRAY[key_idx]) {
142         KEY_ARRAY[key_idx] = calloc(AES_KEY_SIZE, sizeof(unsigned char));
143     } else {
144         memset(KEY_ARRAY[key_idx], 0, AES_KEY_SIZE);
145     }
146
147     if (1 != RAND_bytes(KEY_ARRAY[key_idx], AES_KEY_SIZE))
148         FREE_OUT(KEY_ARRAY[key_idx], KMSB_ERROR_OPERATION_FAILED)
149
150     return KMSB_ERROR_NONE;
151 }
152
153 static kmsb_error_e generate_ecdsa_key(const unsigned int key_idx, 
154                         kmsb_ec_type_e ec, const bool delete_old)
155 {
156     if (!delete_old && KEY_ARRAY[key_idx])
157         return KMSB_ERROR_NOT_PERMITTED;
158
159     /* Create the context for generating the parameters */
160     EVP_PKEY_CTX *pctx = NULL;
161     EVP_PKEY *pkey = NULL;
162     if (!(pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL)))
163         return KMSB_ERROR_OPERATION_FAILED;
164     if (!EVP_PKEY_paramgen_init(pctx))
165         return KMSB_ERROR_OPERATION_FAILED;
166
167     uint32_t idx = 0;
168     int32_t nid = 0;
169     switch (ec) {
170     case KMSB_EC_PRIME192V1:
171         nid = NID_X9_62_prime192v1;
172         idx = EC_P192_KEY_IDX;
173         break;
174     case KMSB_EC_PRIME256V1:
175         nid = NID_X9_62_prime256v1;
176         idx = EC_P256_KEY_IDX;
177         break;
178     case KMSB_EC_SECP384R1:
179         nid = NID_secp384r1;
180         idx = EC_S384_KEY_IDX;
181         break;
182     default:
183         return KMSB_ERROR_NOT_SUPPORTED;
184     }
185     if (idx != key_idx)
186         return KMSB_ERROR_INVALID_PARAMETER;
187
188     /* Use the NID_X9_62_prime256v1 named curve - defined in obj_mac.h */
189     if (!EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, nid))
190         return KMSB_ERROR_OPERATION_FAILED;
191
192     if (!EVP_PKEY_keygen_init(pctx))
193         return KMSB_ERROR_OPERATION_FAILED;
194     /* Generate the key */
195     if (!EVP_PKEY_keygen(pctx, &pkey))
196         return KMSB_ERROR_OPERATION_FAILED;
197     if (pkey == NULL)
198         return KMSB_ERROR_OPERATION_FAILED;
199
200     KEY_ARRAY[key_idx] = (unsigned char*)pkey;
201     return KMSB_ERROR_NONE;
202 }
203
204 static kmsb_error_e aes_gcm_encrypt(EVP_CIPHER_CTX *ctx, kmsb_aes_param_s *param, uint8_t *key,
205                      const unsigned char *input, const unsigned int input_len,
206                      unsigned char **output, unsigned int *output_len)
207  {
208     int clen = 0, flen = 0;
209     unsigned char* buf = NULL;
210
211     /* Initialise the encryption operation. */
212     if (OPENSSL_SUCCESS != EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL))
213         return KMSB_ERROR_OPERATION_FAILED;
214     /*
215      * Set IV length if default 12 bytes (96 bits) is not appropriate
216      */
217     if (OPENSSL_SUCCESS != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, param->iv_len, NULL))
218         return KMSB_ERROR_OPERATION_FAILED;
219
220     /* Initialise key and IV */
221     if (OPENSSL_SUCCESS != EVP_EncryptInit_ex(ctx, NULL, NULL, key, param->iv))
222         return KMSB_ERROR_OPERATION_FAILED;
223
224     clen = input_len + EVP_CIPHER_CTX_block_size(ctx);
225     buf = calloc(clen, sizeof(unsigned char));
226     if (!buf) return KMSB_ERROR_OUT_OF_MEMORY;
227
228     /*
229      * Set Padding zero forcely, with our concept, there should be no padding 
230      * to increase buffer size.
231      */
232     if (OPENSSL_SUCCESS != EVP_CIPHER_CTX_set_padding(ctx, 0))
233         FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
234     /*
235      * Provide any AAD data. This can be called zero or more times as
236      * required
237      */
238     if (OPENSSL_SUCCESS != EVP_EncryptUpdate(ctx, NULL, &clen, param->aad, param->aad_len))
239         FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
240     /*
241      * Provide the message to be encrypted, and obtain the encrypted output.
242      * EVP_EncryptUpdate can be called multiple times if necessary
243      */
244     if (OPENSSL_SUCCESS != EVP_EncryptUpdate(ctx, buf, &clen, input, input_len))
245         FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
246     /*
247      * Finalise the encryption. Normally ciphertext bytes may be written at
248      * this stage, but this does not occur in GCM mode
249      */
250     if (OPENSSL_SUCCESS != EVP_EncryptFinal_ex(ctx, buf + clen, &flen))
251         FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
252     *output_len = clen + flen;
253
254     /* Get the tag */
255     if (OPENSSL_SUCCESS != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, param->tag))
256         FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
257
258     *output = calloc(*output_len, sizeof(unsigned char));
259     if (output == NULL)
260         FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OUT_OF_MEMORY)
261     memcpy(*output, buf, *output_len);
262
263     FREE_OUT_CTX(ctx, buf, KMSB_ERROR_NONE)
264 }
265
266 static kmsb_error_e aes_gcm_decrypt(EVP_CIPHER_CTX *ctx, kmsb_aes_param_s *param, uint8_t *key,
267                      const unsigned char *input, const unsigned int input_len,
268                      unsigned char **output, unsigned int *output_len)
269  {
270     int clen = 0, flen = 0;
271     unsigned char* buf = NULL;
272
273     /* Initialise the decryption operation. */
274     if (OPENSSL_SUCCESS != EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL))
275         return KMSB_ERROR_OPERATION_FAILED;
276     /*
277      * Set IV length if default 12 bytes (96 bits) is not appropriate
278      */
279     if (OPENSSL_SUCCESS != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, param->iv_len, NULL))
280         return KMSB_ERROR_OPERATION_FAILED;
281     /* Initialise key and IV */
282     if (OPENSSL_SUCCESS != EVP_DecryptInit_ex(ctx, NULL, NULL, key, param->iv))
283         return KMSB_ERROR_OPERATION_FAILED;
284     clen = input_len + EVP_CIPHER_CTX_block_size(ctx);
285     buf = calloc(clen, sizeof(unsigned char));
286     if (!buf) return KMSB_ERROR_OUT_OF_MEMORY;
287     /*
288      * Set Padding zero forcely, with our concept, there should be no padding 
289      * to increase buffer size.
290      */
291     if (OPENSSL_SUCCESS != EVP_CIPHER_CTX_set_padding(ctx, 0))
292         FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
293     /*
294      * Provide any AAD data. This can be called zero or more times as
295      * required
296      */
297     if (OPENSSL_SUCCESS != EVP_DecryptUpdate(ctx, NULL, &clen, param->aad, param->aad_len))
298         FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
299     /*
300      * Provide the message to be decrypted, and obtain the plaintext output.
301      * EVP_DecryptUpdate can be called multiple times if necessary
302      */
303     if (OPENSSL_SUCCESS != EVP_DecryptUpdate(ctx, buf, &clen, input, input_len))
304         FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
305     /* Set expected tag value. Works in OpenSSL 1.0.1d and later */
306     if (OPENSSL_SUCCESS != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, param->tag))
307         FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
308     /*
309      * Finalise the decryption. A positive return value indicates success,
310      * anything else is a failure - the plaintext is not trustworthy.
311      */
312     if (OPENSSL_SUCCESS != EVP_DecryptFinal_ex(ctx, buf + clen, &flen))
313         FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
314     *output_len = clen + flen;
315
316     *output = calloc(*output_len, sizeof(unsigned char));
317     if (output == NULL)
318         FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OUT_OF_MEMORY)
319     memcpy(*output, buf, *output_len);
320
321     FREE_OUT_CTX(ctx, buf, KMSB_ERROR_NONE)
322 }
323
324 kmsb_error_e kmsb_aes_encrypt(const unsigned int key_idx,
325                     kmsb_aes_param_s *param,
326                     const unsigned char *input, const unsigned int input_len,
327                     unsigned char **output, unsigned int *output_len)
328 {
329     // check the input parameters
330     if (input == NULL ||
331         input_len == 0 ||
332         output == NULL ||
333         output_len == NULL ||
334         param->iv == NULL ||
335         param->iv_len == 0)
336         return KMSB_ERROR_INVALID_PARAMETER;
337
338     // check the validate of key_idx
339     if (key_idx != AES_KEY_IDX) return KMSB_ERROR_INVALID_PARAMETER;
340     if (!KEY_ARRAY[key_idx]) {
341         if (KMSB_ERROR_NONE != generate_aes_key(key_idx, false))
342             return KMSB_ERROR_NO_KEY;
343     }
344
345     int ret = 0;
346     int clen = 0, flen = 0;
347     unsigned char* buf = NULL;
348     unsigned char* key = KEY_ARRAY[key_idx];
349     EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
350     
351     switch (param->mode) {
352     case KMSB_ALGO_AES_CTR:
353         ret = EVP_EncryptInit_ex(ctx, EVP_aes_256_ctr(), NULL, key, param->iv);
354         break;
355     case KMSB_ALGO_AES_CBC:
356         ret = EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, param->iv);
357         break;
358     case KMSB_ALGO_AES_GCM:
359         return aes_gcm_encrypt(ctx, param, key, input, input_len, output, output_len);
360     case KMSB_ALGO_AES_CFB:
361         ret = EVP_EncryptInit_ex(ctx, EVP_aes_256_cfb8(), NULL, key, param->iv);
362         break;
363     default:
364         return KMSB_ERROR_NOT_SUPPORTED;
365     }
366     if (OPENSSL_SUCCESS != ret) return KMSB_ERROR_OPERATION_FAILED;
367
368     clen = input_len + EVP_CIPHER_CTX_block_size(ctx);
369     buf = calloc(clen, sizeof(unsigned char));
370     if (!buf) return KMSB_ERROR_OUT_OF_MEMORY;
371
372     /*
373      * Set Padding zero forcely, with our concept, there should be no padding 
374      * to increase buffer size.
375      */
376     if (OPENSSL_SUCCESS != EVP_CIPHER_CTX_set_padding(ctx, 0))
377         FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
378     /*
379      * Provide the message to be encrypted, and obtain the encrypted output.
380      * EVP_EncryptUpdate can be called multiple times if necessary
381      */
382     if (OPENSSL_SUCCESS != EVP_EncryptUpdate(ctx, buf, &clen, input, input_len))
383         FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
384     /*
385      * Finalise the encryption. Further ciphertext bytes may be written at
386      * this stage.
387      */
388     if (OPENSSL_SUCCESS != EVP_EncryptFinal_ex(ctx, buf + clen, &flen))
389         FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
390     *output_len = clen + flen;
391
392     *output = calloc(*output_len, sizeof(unsigned char));
393     if (output == NULL)
394         FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OUT_OF_MEMORY)
395     memcpy(*output, buf, *output_len);
396
397     FREE_OUT_CTX(ctx, buf, KMSB_ERROR_NONE)
398 }
399
400 kmsb_error_e kmsb_aes_decrypt(const unsigned int key_idx,
401                     kmsb_aes_param_s *param,
402                     const unsigned char *input, const unsigned int input_len,
403                     unsigned char **output, unsigned int *output_len)
404 {
405     // check the input parameters
406     if (input == NULL ||
407         input_len == 0 ||
408         output == NULL ||
409         output_len == NULL ||
410         param->iv == NULL ||
411         param->iv_len == 0)
412         return KMSB_ERROR_INVALID_PARAMETER;
413
414     // check the validate of key_idx
415     if (key_idx != AES_KEY_IDX) return KMSB_ERROR_INVALID_PARAMETER;
416     if (!KEY_ARRAY[key_idx]) {
417         if (KMSB_ERROR_NONE != generate_aes_key(key_idx, false))
418             return KMSB_ERROR_NO_KEY;
419     }
420
421     int ret = 0;
422     int clen = 0, flen = 0;
423     unsigned char* buf = NULL;
424     unsigned char* key = KEY_ARRAY[key_idx];
425     EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
426
427     switch (param->mode) {
428     case KMSB_ALGO_AES_CTR:
429         ret = EVP_DecryptInit_ex(ctx, EVP_aes_256_ctr(), NULL, key, param->iv);
430         break;
431     case KMSB_ALGO_AES_CBC:
432         ret = EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, param->iv);
433         break;
434     case KMSB_ALGO_AES_GCM:
435         return aes_gcm_decrypt(ctx, param, key, input, input_len, output, output_len);
436     case KMSB_ALGO_AES_CFB:
437         ret = EVP_DecryptInit_ex(ctx, EVP_aes_256_cfb8(), NULL, key, param->iv);
438         break;
439     default:
440         return KMSB_ERROR_NOT_SUPPORTED;
441     }
442     if (OPENSSL_SUCCESS != ret) return KMSB_ERROR_OPERATION_FAILED;
443
444     clen = input_len + EVP_CIPHER_CTX_block_size(ctx);
445     buf = calloc(clen, sizeof(unsigned char));
446     if (!buf) return KMSB_ERROR_OUT_OF_MEMORY;
447
448     /*
449      * Set Padding zero forcely, with our concept, there should be no padding 
450      * to increase buffer size.
451      */
452     if (OPENSSL_SUCCESS != EVP_CIPHER_CTX_set_padding(ctx, 0))
453         FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
454     /*
455      * Provide the message to be decrypted, and obtain the plaintext output.
456      * EVP_DecryptUpdate can be called multiple times if necessary
457      */
458     if (OPENSSL_SUCCESS != EVP_DecryptUpdate(ctx, buf, &clen, input, input_len))
459        FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
460     /*
461      * Finalise the decryption. Further plaintext bytes may be written at
462      * this stage.
463      */
464     if (OPENSSL_SUCCESS != EVP_DecryptFinal_ex(ctx, buf + clen, &flen))
465         FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
466     *output_len = clen + flen;
467
468     *output = calloc(*output_len, sizeof(unsigned char));
469     if (output == NULL)
470         FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OUT_OF_MEMORY)
471
472     memcpy(*output, buf, *output_len);
473     FREE_OUT_CTX(ctx, buf, KMSB_ERROR_NONE)
474 }
475
476 const EVP_MD *getMdAlgo(kmsb_hash_algo_e hash)
477 {
478     switch (hash) {
479     case KMSB_HASH_SHA1:
480         return EVP_sha1();
481     case KMSB_HASH_SHA256:
482         return EVP_sha256();
483     case KMSB_HASH_SHA384:
484         return EVP_sha384();
485     case KMSB_HASH_SHA512:
486         return EVP_sha512();
487     default:
488         return NULL;
489     }
490 }
491
492 kmsb_error_e kmsb_create_signature(const unsigned int key_idx,
493                 const kmsb_sign_param_s *param,
494                 const unsigned char *msg, const unsigned int msg_len,
495                 unsigned char **sig, unsigned int *sig_len)
496 {
497     // check the input parameters
498     if (msg == NULL ||
499         msg_len == 0 ||
500         sig == NULL ||
501         sig_len == NULL)
502         return KMSB_ERROR_INVALID_PARAMETER;
503
504     kmsb_error_e ret = KMSB_ERROR_NONE;
505     if (!KEY_ARRAY[key_idx]) {
506         ret = generate_ecdsa_key(key_idx, param->ec_type, false);
507         if (KMSB_ERROR_NONE != ret)
508             return ret;
509     }
510
511     EVP_PKEY *pkey = (EVP_PKEY *)KEY_ARRAY[key_idx];
512     EVP_MD_CTX *mdctx = NULL;
513     /* Create the Message Digest Context */
514     if (!(mdctx = EVP_MD_CTX_create()))
515         return KMSB_ERROR_OPERATION_FAILED;
516
517     const EVP_MD* hash = getMdAlgo(param->hash_algo);
518     if (hash == NULL) return KMSB_ERROR_NOT_SUPPORTED;
519
520     /* Initialise the DigestSign operation - SHA-256 has been selected as the message digest function in this example */
521     if (OPENSSL_SUCCESS != EVP_DigestSignInit(mdctx, NULL, hash, NULL, pkey))
522         return KMSB_ERROR_OPERATION_FAILED;
523
524     /* Call update with the message */
525     if (OPENSSL_SUCCESS != EVP_DigestSignUpdate(mdctx, msg, msg_len))
526         return KMSB_ERROR_OPERATION_FAILED;
527
528     /* Finalise the DigestSign operation */
529     /* First call EVP_DigestSignFinal with a NULL sig parameter to obtain the length of the
530      * signature. Length is returned in slen */
531     if (OPENSSL_SUCCESS != EVP_DigestSignFinal(mdctx, NULL, sig_len))
532         return KMSB_ERROR_OPERATION_FAILED;
533     /* Allocate memory for the signature based on size in slen */
534     if (!(*sig = OPENSSL_malloc(sizeof(unsigned char) * (*sig_len))))
535         return KMSB_ERROR_OUT_OF_MEMORY;
536     /* Obtain the signature */
537     if (OPENSSL_SUCCESS != EVP_DigestSignFinal(mdctx, *sig, sig_len))
538         return KMSB_ERROR_OPERATION_FAILED;
539
540     /* Clean up */
541     if (mdctx) EVP_MD_CTX_destroy(mdctx);
542     return KMSB_ERROR_NONE;
543 }
544
545 kmsb_error_e kmsb_verify_signature(const unsigned int key_idx,
546                 const kmsb_sign_param_s *param,
547                 const unsigned char *msg, const unsigned int msg_len,
548                 unsigned char *sig, unsigned int sig_len)
549 {
550     // check the input parameters
551     if (msg == NULL ||
552         msg_len == 0 ||
553         sig == NULL ||
554         sig_len == 0)
555         return KMSB_ERROR_INVALID_PARAMETER;
556
557     kmsb_error_e ret = KMSB_ERROR_NONE;
558     if (!KEY_ARRAY[key_idx]) {
559         ret = generate_ecdsa_key(key_idx, param->ec_type, false);
560         if (KMSB_ERROR_NONE != ret)
561             return ret;
562     }
563
564     EVP_PKEY *pkey = (EVP_PKEY *)KEY_ARRAY[key_idx];
565     EVP_MD_CTX *mdctx = NULL;
566     /* Create the Message Digest Context */
567     if (!(mdctx = EVP_MD_CTX_create()))
568         return KMSB_ERROR_OPERATION_FAILED;
569
570     const EVP_MD* hash = getMdAlgo(param->hash_algo);
571     if (hash == NULL) return KMSB_ERROR_NOT_SUPPORTED;
572
573     if (OPENSSL_SUCCESS != EVP_DigestVerifyInit(mdctx, NULL, hash, NULL, pkey))
574         return KMSB_ERROR_OPERATION_FAILED;
575
576     /* Initialize `key` with a public key */
577     if (OPENSSL_SUCCESS != EVP_DigestVerifyUpdate(mdctx, msg, msg_len))
578         return KMSB_ERROR_OPERATION_FAILED;
579     if (OPENSSL_SUCCESS != EVP_DigestVerifyFinal(mdctx, sig, sig_len))
580         return KMSB_ERROR_VERIFICATION_FAILED;
581
582     return KMSB_ERROR_NONE;
583 }
584
585 int kmsb_get_key(const unsigned int key_idx, unsigned char **output, unsigned int *output_len)
586 {
587     (void) key_idx;
588     (void) output;
589     (void) output_len;
590     return KMSB_ERROR_NOT_SUPPORTED;
591 }
592
593 int kmsb_get_certificate(const unsigned int cert_idx, unsigned char **output, unsigned int *output_len)
594 {
595     (void) cert_idx;
596     (void) output;
597     (void) output_len;
598     return KMSB_ERROR_NOT_SUPPORTED;
599 }
600
601 int kmsb_get_data(const unsigned int data_idx, unsigned char **output, unsigned int *output_len)
602 {
603     (void) data_idx;
604     (void) output;
605     (void) output_len;
606     return KMSB_ERROR_NOT_SUPPORTED;
607 }