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 OPENSSL_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 (OPENSSL_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 (OPENSSL_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 (OPENSSL_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 (OPENSSL_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 (OPENSSL_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 (OPENSSL_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 (OPENSSL_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 (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)
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 (OPENSSL_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 (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;
288 * Set Padding zero forcely, with our concept, there should be no padding
289 * to increase buffer size.
291 if (OPENSSL_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 (OPENSSL_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 (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)
309 * Finalise the decryption. A positive return value indicates success,
310 * anything else is a failure - the plaintext is not trustworthy.
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;
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 input parameters
333 output_len == NULL ||
336 return KMSB_ERROR_INVALID_PARAMETER;
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;
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();
351 switch (param->mode) {
352 case KMSB_ALGO_AES_CTR:
353 ret = EVP_EncryptInit_ex(ctx, EVP_aes_256_ctr(), NULL, key, param->iv);
355 case KMSB_ALGO_AES_CBC:
356 ret = EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, param->iv);
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);
364 return KMSB_ERROR_NOT_SUPPORTED;
366 if (OPENSSL_SUCCESS != ret) return KMSB_ERROR_OPERATION_FAILED;
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;
373 * Set Padding zero forcely, with our concept, there should be no padding
374 * to increase buffer size.
376 if (OPENSSL_SUCCESS != EVP_CIPHER_CTX_set_padding(ctx, 0))
377 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
379 * Provide the message to be encrypted, and obtain the encrypted output.
380 * EVP_EncryptUpdate can be called multiple times if necessary
382 if (OPENSSL_SUCCESS != EVP_EncryptUpdate(ctx, buf, &clen, input, input_len))
383 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
385 * Finalise the encryption. Further ciphertext bytes may be written at
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;
392 *output = calloc(*output_len, sizeof(unsigned char));
394 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OUT_OF_MEMORY)
395 memcpy(*output, buf, *output_len);
397 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_NONE)
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)
405 // check the input parameters
409 output_len == NULL ||
412 return KMSB_ERROR_INVALID_PARAMETER;
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;
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();
427 switch (param->mode) {
428 case KMSB_ALGO_AES_CTR:
429 ret = EVP_DecryptInit_ex(ctx, EVP_aes_256_ctr(), NULL, key, param->iv);
431 case KMSB_ALGO_AES_CBC:
432 ret = EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, param->iv);
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);
440 return KMSB_ERROR_NOT_SUPPORTED;
442 if (OPENSSL_SUCCESS != ret) return KMSB_ERROR_OPERATION_FAILED;
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;
449 * Set Padding zero forcely, with our concept, there should be no padding
450 * to increase buffer size.
452 if (OPENSSL_SUCCESS != EVP_CIPHER_CTX_set_padding(ctx, 0))
453 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
455 * Provide the message to be decrypted, and obtain the plaintext output.
456 * EVP_DecryptUpdate can be called multiple times if necessary
458 if (OPENSSL_SUCCESS != EVP_DecryptUpdate(ctx, buf, &clen, input, input_len))
459 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OPERATION_FAILED)
461 * Finalise the decryption. Further plaintext bytes may be written at
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;
468 *output = calloc(*output_len, sizeof(unsigned char));
470 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_OUT_OF_MEMORY)
472 memcpy(*output, buf, *output_len);
473 FREE_OUT_CTX(ctx, buf, KMSB_ERROR_NONE)
476 const EVP_MD *getMdAlgo(kmsb_hash_algo_e hash)
481 case KMSB_HASH_SHA256:
483 case KMSB_HASH_SHA384:
485 case KMSB_HASH_SHA512:
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)
497 // check the input parameters
502 return KMSB_ERROR_INVALID_PARAMETER;
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)
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;
517 const EVP_MD* hash = getMdAlgo(param->hash_algo);
518 if (hash == NULL) return KMSB_ERROR_NOT_SUPPORTED;
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;
524 /* Call update with the message */
525 if (OPENSSL_SUCCESS != EVP_DigestSignUpdate(mdctx, msg, msg_len))
526 return KMSB_ERROR_OPERATION_FAILED;
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;
541 if (mdctx) EVP_MD_CTX_destroy(mdctx);
542 return KMSB_ERROR_NONE;
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)
550 // check the input parameters
555 return KMSB_ERROR_INVALID_PARAMETER;
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)
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;
570 const EVP_MD* hash = getMdAlgo(param->hash_algo);
571 if (hash == NULL) return KMSB_ERROR_NOT_SUPPORTED;
573 if (OPENSSL_SUCCESS != EVP_DigestVerifyInit(mdctx, NULL, hash, NULL, pkey))
574 return KMSB_ERROR_OPERATION_FAILED;
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;
582 return KMSB_ERROR_NONE;
585 int kmsb_get_key(const unsigned int key_idx, unsigned char **output, unsigned int *output_len)
590 return KMSB_ERROR_NOT_SUPPORTED;
593 int kmsb_get_certificate(const unsigned int cert_idx, unsigned char **output, unsigned int *output_len)
598 return KMSB_ERROR_NOT_SUPPORTED;
601 int kmsb_get_data(const unsigned int data_idx, unsigned char **output, unsigned int *output_len)
606 return KMSB_ERROR_NOT_SUPPORTED;