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,};
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 EVP_SUCCESS = 1;
59 #define FREE_OUT_CTX(ctx, buf, result) \
61 EVP_CIPHER_CTX_free(ctx); \
65 #define FREE_OUT(buf, result) \
70 //################################################################################
71 // For Supporting Key Manager DB Encryption with SE Key
72 //################################################################################
73 kmsb_error_e kmsb_generate_dbp_key(const bool delete_old)
75 if (!delete_old && KEY_ARRAY[DBP_KEY_IDX])
76 return KMSB_ERROR_NOT_PERMITTED;
78 if (!KEY_ARRAY[DBP_KEY_IDX]) {
79 KEY_ARRAY[DBP_KEY_IDX] = calloc(DBP_KEY_SIZE, sizeof(unsigned char));
81 memset(KEY_ARRAY[DBP_KEY_IDX], 0, DBP_KEY_SIZE);
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);
88 return KMSB_ERROR_NONE;
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)
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;
102 input_len == 0 || input_len % aes_block_size != 0 ||
104 iv_len != aes_block_size ||
107 return KMSB_ERROR_INVALID_PARAMETER;
110 AES_set_encrypt_key(KEY_ARRAY[DBP_KEY_IDX], DBP_KEY_SIZE*8, &aes_key);
112 *output = malloc(input_len);
114 return KMSB_ERROR_OUT_OF_MEMORY;
115 *output_len = input_len;
117 unsigned char *iv_temp = malloc(iv_len);
119 return KMSB_ERROR_OUT_OF_MEMORY;
120 memcpy(iv_temp, iv, iv_len);
122 AES_cbc_encrypt(input,
129 return KMSB_ERROR_NONE;
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)
138 if (!delete_old && KEY_ARRAY[key_idx])
139 return KMSB_ERROR_NOT_PERMITTED;
141 if (!KEY_ARRAY[key_idx]) {
142 KEY_ARRAY[key_idx] = calloc(AES_KEY_SIZE, sizeof(unsigned char));
144 memset(KEY_ARRAY[key_idx], 0, AES_KEY_SIZE);
147 if (1 != RAND_bytes(KEY_ARRAY[key_idx], AES_KEY_SIZE))
148 FREE_OUT(KEY_ARRAY[key_idx], KMSB_ERROR_OPERATION_FAILED)
150 return KMSB_ERROR_NONE;
153 static kmsb_error_e generate_ecdsa_key(const unsigned int key_idx,
154 kmsb_ec_type_e ec, const bool delete_old)
156 if (!delete_old && KEY_ARRAY[key_idx])
157 return KMSB_ERROR_NOT_PERMITTED;
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;
170 case KMSB_EC_PRIME192V1:
171 nid = NID_X9_62_prime192v1;
172 idx = EC_P192_KEY_IDX;
174 case KMSB_EC_PRIME256V1:
175 nid = NID_X9_62_prime256v1;
176 idx = EC_P256_KEY_IDX;
178 case KMSB_EC_SECP384R1:
180 idx = EC_S384_KEY_IDX;
183 return KMSB_ERROR_NOT_SUPPORTED;
186 return KMSB_ERROR_INVALID_PARAMETER;
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;
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;
198 return KMSB_ERROR_OPERATION_FAILED;
200 KEY_ARRAY[key_idx] = (unsigned char*)pkey;
201 return KMSB_ERROR_NONE;
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)
208 int clen = 0, flen = 0;
209 unsigned char* buf = NULL;
211 /* Initialise the encryption operation. */
212 if(EVP_SUCCESS != EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL))
213 return KMSB_ERROR_OPERATION_FAILED;
215 * Set IV length if default 12 bytes (96 bits) is not appropriate
217 if(EVP_SUCCESS != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, param->iv_len, NULL))
218 return KMSB_ERROR_OPERATION_FAILED;
220 /* Initialise key and IV */
221 if(EVP_SUCCESS != EVP_EncryptInit_ex(ctx, NULL, NULL, key, param->iv))
222 return KMSB_ERROR_OPERATION_FAILED;
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;
229 * Set Padding zero forcely, with our concept, there should be no padding
230 * to increase buffer size.
232 if(EVP_SUCCESS != EVP_CIPHER_CTX_set_padding(ctx, 0))
233 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
235 * Provide any AAD data. This can be called zero or more times as
238 if(EVP_SUCCESS != EVP_EncryptUpdate(ctx, NULL, &clen, param->aad, param->aad_len))
239 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
241 * Provide the message to be encrypted, and obtain the encrypted output.
242 * EVP_EncryptUpdate can be called multiple times if necessary
244 if(EVP_SUCCESS != EVP_EncryptUpdate(ctx, buf, &clen, input, input_len))
245 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
247 * Finalise the encryption. Normally ciphertext bytes may be written at
248 * this stage, but this does not occur in GCM mode
250 if(EVP_SUCCESS != EVP_EncryptFinal_ex(ctx, buf + clen, &flen))
251 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
252 *output_len = clen + flen;
255 if(EVP_SUCCESS != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, param->tag))
256 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
258 *output = calloc(*output_len, sizeof(unsigned char));
260 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OUT_OF_MEMORY)
261 memcpy(*output, buf, *output_len);
263 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_NONE)
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)
270 int clen = 0, flen = 0;
271 unsigned char* buf = NULL;
273 /* Initialise the decryption operation. */
274 if(EVP_SUCCESS != EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL))
275 return KMSB_ERROR_OPERATION_FAILED;
277 * Set IV length if default 12 bytes (96 bits) is not appropriate
279 if(EVP_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(EVP_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;
288 * Set Padding zero forcely, with our concept, there should be no padding
289 * to increase buffer size.
291 if(EVP_SUCCESS != EVP_CIPHER_CTX_set_padding(ctx, 0))
292 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
294 * Provide any AAD data. This can be called zero or more times as
297 if(EVP_SUCCESS != EVP_DecryptUpdate(ctx, NULL, &clen, param->aad, param->aad_len))
298 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
300 * Provide the message to be decrypted, and obtain the plaintext output.
301 * EVP_DecryptUpdate can be called multiple times if necessary
303 if(EVP_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(EVP_SUCCESS != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, param->tag))
307 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
309 * Finalise the decryption. A positive return value indicates success,
310 * anything else is a failure - the plaintext is not trustworthy.
312 if(EVP_SUCCESS != EVP_DecryptFinal_ex(ctx, buf + clen, &flen))
313 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
314 *output_len = clen + flen;
316 *output = calloc(*output_len, sizeof(unsigned char));
318 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OUT_OF_MEMORY)
319 memcpy(*output, buf, *output_len);
321 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_NONE)
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)
329 // check the validate of key_idx
330 if (key_idx != AES_KEY_IDX) return KMSB_ERROR_INVALID_PARAMETER;
331 if (!KEY_ARRAY[key_idx]) {
332 if (KMSB_ERROR_NONE != generate_aes_key(key_idx, false))
333 return KMSB_ERROR_NO_KEY;
335 // check the input parameters
340 return KMSB_ERROR_INVALID_PARAMETER;
343 int clen = 0, flen = 0;
344 unsigned char* buf = NULL;
345 unsigned char* key = KEY_ARRAY[key_idx];
346 EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
348 switch (param->mode) {
349 case KMSB_ALGO_AES_CTR:
350 ret = EVP_EncryptInit_ex(ctx, EVP_aes_256_ctr(), NULL, key, param->iv);
352 case KMSB_ALGO_AES_CBC:
353 ret = EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, param->iv);
355 case KMSB_ALGO_AES_GCM:
356 return aes_gcm_encrypt(ctx, param, key, input, input_len, output, output_len);
357 case KMSB_ALGO_AES_CFB:
358 ret = EVP_EncryptInit_ex(ctx, EVP_aes_256_cfb8(), NULL, key, param->iv);
361 return KMSB_ERROR_NOT_SUPPORTED;
363 if(EVP_SUCCESS != ret) return KMSB_ERROR_OPERATION_FAILED;
365 clen = input_len + EVP_CIPHER_CTX_block_size(ctx);
366 buf = calloc(clen, sizeof(unsigned char));
367 if (!buf) return KMSB_ERROR_OUT_OF_MEMORY;
370 * Set Padding zero forcely, with our concept, there should be no padding
371 * to increase buffer size.
373 if(EVP_SUCCESS != EVP_CIPHER_CTX_set_padding(ctx, 0))
374 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
376 * Provide the message to be encrypted, and obtain the encrypted output.
377 * EVP_EncryptUpdate can be called multiple times if necessary
379 if(EVP_SUCCESS != EVP_EncryptUpdate(ctx, buf, &clen, input, input_len))
380 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
384 * Finalise the encryption. Further ciphertext bytes may be written at
387 if(EVP_SUCCESS != EVP_EncryptFinal_ex(ctx, buf + clen, &flen))
388 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
391 *output = calloc(*output_len, sizeof(unsigned char));
393 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OUT_OF_MEMORY)
394 memcpy(*output, buf, *output_len);
396 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_NONE)
399 kmsb_error_e kmsb_aes_decrypt(const unsigned int key_idx,
400 kmsb_aes_param_s *param,
401 const unsigned char *input, const unsigned int input_len,
402 unsigned char **output, unsigned int *output_len)
404 // check the validate of key_idx
405 if (key_idx != AES_KEY_IDX) return KMSB_ERROR_INVALID_PARAMETER;
406 if (!KEY_ARRAY[key_idx]) {
407 if (KMSB_ERROR_NONE != generate_aes_key(key_idx, false))
408 return KMSB_ERROR_NO_KEY;
410 // check the input parameters
414 output_len == NULL ||
417 return KMSB_ERROR_INVALID_PARAMETER;
420 int clen = 0, flen = 0;
421 unsigned char* buf = NULL;
422 unsigned char* key = KEY_ARRAY[key_idx];
423 EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
425 switch (param->mode) {
426 case KMSB_ALGO_AES_CTR:
427 ret = EVP_DecryptInit_ex(ctx, EVP_aes_256_ctr(), NULL, key, param->iv);
429 case KMSB_ALGO_AES_CBC:
430 ret = EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, param->iv);
432 case KMSB_ALGO_AES_GCM:
433 return aes_gcm_decrypt(ctx, param, key, input, input_len, output, output_len);
434 case KMSB_ALGO_AES_CFB:
435 ret = EVP_DecryptInit_ex(ctx, EVP_aes_256_cfb8(), NULL, key, param->iv);
438 return KMSB_ERROR_NOT_SUPPORTED;
440 if(EVP_SUCCESS != ret) return KMSB_ERROR_OPERATION_FAILED;
442 clen = input_len + EVP_CIPHER_CTX_block_size(ctx);
443 buf = calloc(clen, sizeof(unsigned char));
444 if (!buf) return KMSB_ERROR_OUT_OF_MEMORY;
447 * Set Padding zero forcely, with our concept, there should be no padding
448 * to increase buffer size.
450 if(EVP_SUCCESS != EVP_CIPHER_CTX_set_padding(ctx, 0))
451 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
453 * Provide the message to be decrypted, and obtain the plaintext output.
454 * EVP_DecryptUpdate can be called multiple times if necessary
456 if(EVP_SUCCESS != EVP_DecryptUpdate(ctx, buf, &clen, input, input_len))
457 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
459 * Finalise the decryption. Further plaintext bytes may be written at
462 if(EVP_SUCCESS != EVP_DecryptFinal_ex(ctx, buf + clen, &flen))
463 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
464 *output_len = clen + flen;
466 *output = calloc(*output_len, sizeof(unsigned char));
468 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OUT_OF_MEMORY)
470 memcpy(*output, buf, *output_len);
471 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_NONE)
474 kmsb_error_e kmsb_create_signature(const unsigned int key_idx,
475 const kmsb_sign_param_s *param,
476 const unsigned char *msg, const unsigned int msg_len,
477 unsigned char **sig, unsigned int *sig_len)
479 kmsb_error_e ret = KMSB_ERROR_NONE;
480 if (!KEY_ARRAY[key_idx]) {
481 ret = generate_ecdsa_key(key_idx, param->ec_type, false);
482 if (KMSB_ERROR_NONE != ret)
486 EVP_PKEY *pkey = (EVP_PKEY *)KEY_ARRAY[key_idx];
487 EVP_MD_CTX *mdctx = NULL;
488 /* Create the Message Digest Context */
489 if(!(mdctx = EVP_MD_CTX_create()))
490 return KMSB_ERROR_OPERATION_FAILED;
492 switch (param->hash_algo) {
494 if(EVP_SUCCESS != EVP_DigestSignInit(mdctx, NULL, EVP_sha1(), NULL, pkey))
495 return KMSB_ERROR_OPERATION_FAILED;
497 case KMSB_HASH_SHA256:
498 if(EVP_SUCCESS != EVP_DigestSignInit(mdctx, NULL, EVP_sha256(), NULL, pkey))
499 return KMSB_ERROR_OPERATION_FAILED;
501 case KMSB_HASH_SHA384:
502 if(EVP_SUCCESS != EVP_DigestSignInit(mdctx, NULL, EVP_sha384(), NULL, pkey))
503 return KMSB_ERROR_OPERATION_FAILED;
505 case KMSB_HASH_SHA512:
506 if(EVP_SUCCESS != EVP_DigestSignInit(mdctx, NULL, EVP_sha512(), NULL, pkey))
507 return KMSB_ERROR_OPERATION_FAILED;
510 return KMSB_ERROR_NOT_SUPPORTED;
512 /* Initialise the DigestSign operation - SHA-256 has been selected as the message digest function in this example */
514 /* Call update with the message */
515 if(EVP_SUCCESS != EVP_DigestSignUpdate(mdctx, msg, msg_len))
516 return KMSB_ERROR_OPERATION_FAILED;
518 /* Finalise the DigestSign operation */
519 /* First call EVP_DigestSignFinal with a NULL sig parameter to obtain the length of the
520 * signature. Length is returned in slen */
521 if(EVP_SUCCESS != EVP_DigestSignFinal(mdctx, NULL, sig_len))
522 return KMSB_ERROR_OPERATION_FAILED;
523 /* Allocate memory for the signature based on size in slen */
524 if(!(*sig = OPENSSL_malloc(sizeof(unsigned char) * (*sig_len))))
525 return KMSB_ERROR_OUT_OF_MEMORY;
526 /* Obtain the signature */
527 if(EVP_SUCCESS != EVP_DigestSignFinal(mdctx, *sig, sig_len))
528 return KMSB_ERROR_OPERATION_FAILED;
531 if(mdctx) EVP_MD_CTX_destroy(mdctx);
532 return KMSB_ERROR_NONE;
535 kmsb_error_e kmsb_verify_signature(const unsigned int key_idx,
536 const kmsb_sign_param_s *param,
537 const unsigned char *msg, const unsigned int msg_len,
538 unsigned char *sig, unsigned int sig_len)
540 kmsb_error_e ret = KMSB_ERROR_NONE;
541 if (!KEY_ARRAY[key_idx]) {
542 ret = generate_ecdsa_key(key_idx, param->ec_type, false);
543 if (KMSB_ERROR_NONE != ret)
547 EVP_PKEY *pkey = (EVP_PKEY *)KEY_ARRAY[key_idx];
548 EVP_MD_CTX *mdctx = NULL;
549 /* Create the Message Digest Context */
550 if(!(mdctx = EVP_MD_CTX_create()))
551 return KMSB_ERROR_OPERATION_FAILED;
553 switch (param->hash_algo) {
555 if(EVP_SUCCESS != EVP_DigestVerifyInit(mdctx, NULL, EVP_sha1(), NULL, pkey))
556 return KMSB_ERROR_OPERATION_FAILED;
558 case KMSB_HASH_SHA256:
559 if(EVP_SUCCESS != EVP_DigestVerifyInit(mdctx, NULL, EVP_sha256(), NULL, pkey))
560 return KMSB_ERROR_OPERATION_FAILED;
562 case KMSB_HASH_SHA384:
563 if(EVP_SUCCESS != EVP_DigestVerifyInit(mdctx, NULL, EVP_sha384(), NULL, pkey))
564 return KMSB_ERROR_OPERATION_FAILED;
566 case KMSB_HASH_SHA512:
567 if(EVP_SUCCESS != EVP_DigestVerifyInit(mdctx, NULL, EVP_sha512(), NULL, pkey))
568 return KMSB_ERROR_OPERATION_FAILED;
571 return KMSB_ERROR_NOT_SUPPORTED;
573 /* Initialize `key` with a public key */
574 if(EVP_SUCCESS != EVP_DigestVerifyUpdate(mdctx, msg, msg_len))
575 return KMSB_ERROR_OPERATION_FAILED;
576 if(EVP_SUCCESS != EVP_DigestVerifyFinal(mdctx, sig, sig_len))
577 return KMSB_ERROR_VERIFICATION_FAILED;
579 return KMSB_ERROR_NONE;
582 int kmsb_get_key(const unsigned int key_idx, unsigned char **output, unsigned int *output_len)
587 return KMSB_ERROR_NOT_SUPPORTED;
590 int kmsb_get_certificate(const unsigned int cert_idx, unsigned char **output, unsigned int *output_len)
595 return KMSB_ERROR_NOT_SUPPORTED;
598 int kmsb_get_data(const unsigned int data_idx, unsigned char **output, unsigned int *output_len)
603 return KMSB_ERROR_NOT_SUPPORTED;