Re-organized sub-directory by category
[staging/basesystem.git] / hal / security_hal / src / security_hal.cpp
1 /*
2  * @copyright Copyright (c) 2018-2020 TOYOTA MOTOR CORPORATION.
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 #include "security_hal.h"
17
18 #include <errno.h>
19 #include <stdlib.h>
20 #include <string.h>
21
22 #include "security_hal_securityhallog.h"
23
24 #define MD5_DIGEST_LENGTH 16      // md5 digest length
25 #define SHA1_DIGEST_LENGTH 20     // sha1 digest length
26 #define SHA224_DIGEST_LENGTH 28   // sha224 digest length
27 #define SHA256_DIGEST_LENGTH 32   // sha256 digest length
28 #define SHA384_DIGEST_LENGTH 48   // sha384 digest length
29 #define SHA512_DIGEST_LENGTH 64   // sha512 digest length
30 #define BITS_PER_BYTE 8           // the number of bits per byte
31 #define KEY_SOURCE_SIZE_128  16   // the size of key source is 128 bits
32 #define KEY_SOURCE_SIZE_192  24   // the size of key source is 192 bits
33 #define KEY_SOURCE_SIZE_256  32   // the size of key source is 256 bits
34
35 /**
36  * the max length of input buffer for RSA asymmetric encrypt or
37  * the minimum length of output buffer for RSA asymmetric decrypt
38  */
39 #define RSA_PRIVATE_MAX_SIZE_BYTE \
40         (RSA_PRIVATE_EXPONENT_MAX_SIZE/BITS_PER_BYTE - RSA_PADDING_MINIMUM_SIZE)
41
42 /**
43  * cipher context information
44  */
45 struct CipherContext {
46   enum CipherType cipher_type;
47   union CipherParameter cipher_parameter;
48   union KeyParam key_param;
49 };
50
51 /**
52  * hash context information
53  */
54 struct HashContext {
55   enum HashType hash_type;
56 };
57
58 /**
59  * random number context information
60  */
61 struct RandomContext {
62   uint8_t* seed_buffer;
63   uint32_t buffer_len;
64 };
65
66 bool CheckParameterVaildity(enum CipherType cipher_type,
67                             union CipherParameter* param, union KeyParam* key) {
68   if (SYMMETRIC_CIPHER_AES == cipher_type) {
69     // check cipher mode for symmetric encrypt/decrypt
70     if (SYMMETRIC_CIPHER_MODE_BLOCK_ECB != param->symmetric.mode &&
71         SYMMETRIC_CIPHER_MODE_BLOCK_CBC != param->symmetric.mode &&
72         SYMMETRIC_CIPHER_MODE_BLOCK_CFB != param->symmetric.mode &&
73         SYMMETRIC_CIPHER_MODE_BLOCK_OFB != param->symmetric.mode) {
74       FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
75         "don't support the cipher mode for AES symmetric encrypt/decrypt");
76       return false;
77     }
78     // check cipher block size for AES symmetric encrypt/decrypt
79     if (SYMMETRIC_CIPHER_BLOCK_SIZE_16 != param->symmetric.block_size) {
80       FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
81         "don't support the block size for AES symmetric encrypt/decrypt");
82       return false;
83     }
84     // check cipher key type for AES symmetric encrypt/decrypt
85     if (SYMMETRIC_CIPHER_KEY_TYPE_MANAGED != key->symmetric.key_type &&
86         SYMMETRIC_CIPHER_KEY_TYPE_USER != key->symmetric.key_type) {
87       FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
88         "don't support the cipher key type for AES symmetric encrypt/decrypt");
89       return false;
90     }
91     if (SYMMETRIC_CIPHER_KEY_TYPE_MANAGED == key->symmetric.key_type) {
92       // check cipher rounds for AES symmetric encrypt/decrypt
93       if (SYMMETRIC_CIPHER_ROUND_10 != param->symmetric.round &&
94           SYMMETRIC_CIPHER_ROUND_12 != param->symmetric.round &&
95           SYMMETRIC_CIPHER_ROUND_14 != param->symmetric.round) {
96         FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
97           "don't support the cipher round for AES symmetric encrypt/decrypt");
98         return false;
99      }
100     } else {
101       // check parameter of key provided by user for AES symmetric encrypt/decrypt
102       if (NULL == key->symmetric.key_param.user_key.key) {
103         FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "user_key.key is NULL");
104         return false;
105       }
106       if (KEY_SOURCE_SIZE_128 == key->symmetric.key_param.user_key.key_len) {
107         if (SYMMETRIC_CIPHER_ROUND_10 != param->symmetric.round) {
108           FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
109           "cipher round should be 10 if key len is 128 bits");
110           return false;
111         }
112       } else if (KEY_SOURCE_SIZE_192 == key->symmetric.key_param.user_key.key_len) {
113         if (SYMMETRIC_CIPHER_ROUND_12 != param->symmetric.round) {
114           FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
115           "cipher round should be 12 if key len is 192 bits");
116           return false;
117         }
118       } else if (KEY_SOURCE_SIZE_256 == key->symmetric.key_param.user_key.key_len) {
119         if (SYMMETRIC_CIPHER_ROUND_14 != param->symmetric.round) {
120           FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
121           "cipher round should be 14 if key len is 256 bits");
122           return false;
123         }
124       } else {
125         FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
126           "key len should be 128, 192 or 256 bits for AES symmetric encrypt/decrypt");
127         return false;
128       }
129       if (SYMMETRIC_CIPHER_MODE_BLOCK_ECB != param->symmetric.mode) {
130         if (NULL == key->symmetric.key_param.user_key.iv) {
131           FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "user_key.iv is NULL");
132           return false;
133         }
134         if (key->symmetric.key_param.user_key.iv_len != param->symmetric.block_size) {
135           FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
136           "user_key.iv_len is not equal to block size for AES symmetric encrypt/decrypt");
137           return false;
138         }
139       }
140     }
141   } else if (ASYMMETRIC_CIPHER_RSA == cipher_type) {
142     // check the padding mode for RSA asymmetric encrypt/decrypt
143     if (ASYMMETRIC_PADDING_MODE_RSA_PKCS1 != param->asymmetric.mode &&
144         ASYMMETRIC_PADDING_MODE_RSA_SSLV23 != param->asymmetric.mode &&
145         ASYMMETRIC_PADDING_MODE_RSA_NOPADDING != param->asymmetric.mode &&
146         ASYMMETRIC_PADDING_MODE_RSA_OAEP != param->asymmetric.mode &&
147         ASYMMETRIC_PADDING_MODE_RSA_PSS != param->asymmetric.mode) {
148       FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
149         "don't support the cipher mode for asymmetric encrypt/decrypt");
150       return false;
151     }
152     // check cipher key type for RSA asymmetric encrypt/decrypt
153     if (ASYMMETRIC_CIPHER_KEY_TYPE_MANAGED != key->asymmetric.key_type &&
154         ASYMMETRIC_CIPHER_KEY_TYPE_USER_PUBLIC != key->asymmetric.key_type &&
155         ASYMMETRIC_CIPHER_KEY_TYPE_USER_PRIVATE != key->asymmetric.key_type) {
156       FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
157         "don't support the cipher key type for asymmetric encrypt/decrypt");
158       return false;
159     }
160     if (ASYMMETRIC_CIPHER_KEY_TYPE_USER_PUBLIC == key->asymmetric.key_type) {
161       // check parameter of public key provided by user for RSA asymmetric encrypt/decrypt
162       if (NULL == key->asymmetric.key_param.user_key.public_key) {
163         FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "public_key is NULL");
164         return false;
165       }
166       if (RSA_PUBLIC_EXPONENT_MAX_SIZE <
167           key->asymmetric.key_param.user_key.public_key->rsa.e_length ||
168           RSA_MODULUS_MAX_SIZE <
169           key->asymmetric.key_param.user_key.public_key->rsa.n_length) {
170         FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
171           "e_length or n_length is too large, e_length:%d, n_length:%d",
172           key->asymmetric.key_param.user_key.public_key->rsa.e_length,
173           key->asymmetric.key_param.user_key.public_key->rsa.n_length);
174         return false;
175       }
176     } else if (ASYMMETRIC_CIPHER_KEY_TYPE_USER_PRIVATE == key->asymmetric.key_type) {
177       // check parameter of key provided by user for RSA asymmetric encrypt/decrypt
178       if (NULL == key->asymmetric.key_param.user_key.private_key) {
179         FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "private_key is NULL");
180         return false;
181       }
182       if (RSA_PRIVATE_EXPONENT_MAX_SIZE <
183           key->asymmetric.key_param.user_key.private_key->rsa.d_length ||
184           RSA_MODULUS_MAX_SIZE <
185           key->asymmetric.key_param.user_key.private_key->rsa.n_length) {
186         FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
187           "d_length or n_length is too large, d_length:%d, n_length:%d",
188           key->asymmetric.key_param.user_key.private_key->rsa.d_length,
189           key->asymmetric.key_param.user_key.private_key->rsa.n_length);
190         return false;
191       }
192     }
193   } else {
194     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "the cipher_type isn't support");
195     return false;
196   }
197   return true;
198 }
199
200 // Initialize the encrypt context information
201 EFrameworkunifiedStatus EncryptStart(enum CipherType cipher_type, union CipherParameter* param,
202                         union KeyParam* key, void** ctx) {
203   if (SYMMETRIC_CIPHER_AES != cipher_type && ASYMMETRIC_CIPHER_RSA != cipher_type) {
204     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "the cipher_type isn't support");
205     return eFrameworkunifiedStatusInvldParam;
206   }
207   if (NULL == param || NULL == key || NULL == ctx) {
208     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
209       "param, key or ctx is NULL, param:%p key:%p ctx:%p", param, key, ctx);
210     return eFrameworkunifiedStatusInvldParam;
211   }
212   bool ret = CheckParameterVaildity(cipher_type, param, key);
213   if (true != ret) {
214     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "parameter error");
215     return eFrameworkunifiedStatusInvldParam;
216   }
217
218   void* ctx_temp = malloc(sizeof(CipherContext));
219   if (NULL == ctx_temp) {
220     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Failed to malloc %lu byte for ctx, errno=%d",
221       sizeof(CipherContext), errno);
222     return eFrameworkunifiedStatusFail;
223   }
224   memset(ctx_temp, 0, sizeof(CipherContext));
225   CipherContext* pcipher_context = reinterpret_cast<CipherContext*>(ctx_temp);
226   pcipher_context->cipher_type = cipher_type;
227   pcipher_context->cipher_parameter = *param;
228   pcipher_context->key_param = *key;
229   *ctx = ctx_temp;
230   return eFrameworkunifiedStatusOK;
231 }
232
233 // Encrypt plaintext information
234 EFrameworkunifiedStatus EncryptUpdate(void* ctx, const uint8_t* in, uint32_t in_len,
235                       uint8_t* out, uint32_t out_len, uint32_t* true_length) {
236   if (NULL == ctx || NULL == in || NULL == out || NULL == true_length) {
237     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
238       "ctx, in, out or true_length is NULL, ctx:%p in:%p out:%p true_length:%p",
239       ctx, in, out, true_length);
240     return eFrameworkunifiedStatusInvldParam;
241   }
242   if (0 == in_len) {
243     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "in_len is equal to 0");
244     return eFrameworkunifiedStatusInvldParam;
245   }
246
247   CipherContext* pcipher_context = reinterpret_cast<CipherContext*>(ctx);
248   if (SYMMETRIC_CIPHER_AES == pcipher_context->cipher_type) {  // symmetric encrypt
249     uint32_t block_size = pcipher_context->cipher_parameter.symmetric.block_size;
250     if (out_len < in_len + block_size) {
251       FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "out_len is less than in_len plus block_size");
252       return eFrameworkunifiedStatusInvldParam;
253     }
254     memcpy(out, in, in_len);
255     *true_length = in_len;
256   } else if (ASYMMETRIC_CIPHER_RSA == pcipher_context->cipher_type) {  // asymmetric encrypt
257     if (RSA_PRIVATE_MAX_SIZE_BYTE < in_len) {
258       FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
259         "in_len is greater than RSA_PRIVATE_MAX_SIZE_BYTE");
260       return eFrameworkunifiedStatusInvldParam;
261     }
262     if (RSA_PRIVATE_EXPONENT_MAX_SIZE/BITS_PER_BYTE > out_len) {
263       FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
264         "out_len is less than RSA_PRIVATE_EXPONENT_MAX_SIZE/BITS_PER_BYTE");
265       return eFrameworkunifiedStatusInvldParam;
266     }
267     // out_len is greater than in_len
268     memcpy(out, in, in_len);
269     *true_length = in_len;
270   } else {
271     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
272       "the cipher_type isn't support, cipher_type:%d", pcipher_context->cipher_type);
273     return eFrameworkunifiedStatusInvldParam;
274   }
275
276   return eFrameworkunifiedStatusOK;
277 }
278
279 // Encrypt the final plaintext information
280 EFrameworkunifiedStatus EncryptFinish(void* ctx, uint8_t* out, uint32_t out_len, uint32_t* true_length) {
281   if (NULL == ctx) {
282     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "ctx is NULL");
283     return eFrameworkunifiedStatusInvldParam;
284   }
285   CipherContext* pcipher_context = reinterpret_cast<CipherContext*>(ctx);
286   if (SYMMETRIC_CIPHER_AES == pcipher_context->cipher_type) {  // symmetric encrypt
287     if (NULL == out || NULL == true_length) {
288       FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
289         "out or true_length is NULL, out:%p true_length:%p", out, true_length);
290       return eFrameworkunifiedStatusInvldParam;
291     }
292     uint32_t block_size = pcipher_context->cipher_parameter.symmetric.block_size;
293     if (out_len < block_size) {
294       FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "out_len is less than block_size");
295       return eFrameworkunifiedStatusInvldParam;
296     }
297     if (true == pcipher_context->cipher_parameter.symmetric.to_pad) {
298       // Padding on, the true_length is equal to block_size.
299       *true_length = block_size;
300     } else {
301       // Padding off, true_length is equal to 0.
302       *true_length = 0;
303     }
304   } else if (ASYMMETRIC_CIPHER_RSA == pcipher_context->cipher_type) {
305     // EncryptFinish is useless for RSA asymmetric encrypt. So do nothing.
306   } else {
307     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
308       "the cipher_type isn't support, cipher_type:%d", pcipher_context->cipher_type);
309     return eFrameworkunifiedStatusInvldParam;
310   }
311   return eFrameworkunifiedStatusOK;
312 }
313
314 // Clean up encrypt context information
315 EFrameworkunifiedStatus EncryptCleanup(void* ctx) {
316   if (NULL == ctx) {
317     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "ctx is NULL");
318     return eFrameworkunifiedStatusInvldParam;
319   }
320   memset(ctx, 0, sizeof(CipherContext));
321   free(ctx);
322   return eFrameworkunifiedStatusOK;
323 }
324
325 // Initialize the decrypt context information
326 EFrameworkunifiedStatus DecryptStart(enum CipherType cipher_type, union CipherParameter* param,
327                         union KeyParam *key, void** ctx) {
328   if (SYMMETRIC_CIPHER_AES != cipher_type && ASYMMETRIC_CIPHER_RSA != cipher_type) {
329     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "the cipher_type isn't support");
330     return eFrameworkunifiedStatusInvldParam;
331   }
332   if (NULL == param || NULL == key || NULL == ctx) {
333     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
334       "param, key or ctx is NULL, param:%p key:%p ctx:%p", param, key, ctx);
335     return eFrameworkunifiedStatusInvldParam;
336   }
337   bool ret = CheckParameterVaildity(cipher_type, param, key);
338   if (true != ret) {
339     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "parameter error");
340     return eFrameworkunifiedStatusInvldParam;
341   }
342
343   void* ctx_temp = malloc(sizeof(CipherContext));
344   if (NULL == ctx_temp) {
345     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Failed to malloc %lu byte for ctx, errno=%d",
346            sizeof(CipherContext), errno);
347     return eFrameworkunifiedStatusFail;
348   }
349   memset(ctx_temp, 0, sizeof(CipherContext));
350   CipherContext* pcipher_context = reinterpret_cast<CipherContext*>(ctx_temp);
351   pcipher_context->cipher_type = cipher_type;
352   pcipher_context->cipher_parameter = *param;
353   pcipher_context->key_param = *key;
354   *ctx = ctx_temp;
355   return eFrameworkunifiedStatusOK;
356 }
357
358 // Decrypt ciphertext information
359 EFrameworkunifiedStatus DecryptUpdate(void* ctx, const uint8_t* in, uint32_t in_len,
360                       uint8_t* out, uint32_t out_len, uint32_t* true_length) {
361   if (NULL == ctx || NULL == in || NULL == out || NULL == true_length) {
362     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
363       "ctx, in, out or true_length is NULL, ctx:%p in:%p out:%p true_length:%p",
364       ctx, in, out, true_length);
365     return eFrameworkunifiedStatusInvldParam;
366   }
367
368   CipherContext* pcipher_context = reinterpret_cast<CipherContext*>(ctx);
369   if (SYMMETRIC_CIPHER_AES == pcipher_context->cipher_type) {  // symmetric decrypt
370     if (0 == in_len) {
371       FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "in_len is equal to 0");
372       return eFrameworkunifiedStatusInvldParam;
373     }
374     uint32_t block_size = pcipher_context->cipher_parameter.symmetric.block_size;
375     if (out_len < in_len + block_size) {
376       FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "out_len is less than in_len plus block_size");
377       return eFrameworkunifiedStatusInvldParam;
378     }
379     memcpy(out, in, in_len);
380     *true_length = in_len;
381   } else if (ASYMMETRIC_CIPHER_RSA == pcipher_context->cipher_type) {  // asymmetric decrypt
382     if (RSA_PRIVATE_EXPONENT_MAX_SIZE/BITS_PER_BYTE != in_len) {
383       FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
384         "in_len isn't equal to RSA_PRIVATE_EXPONENT_MAX_SIZE/BITS_PER_BYTE");
385       return eFrameworkunifiedStatusInvldParam;
386     }
387     if (SHA256_DIGEST_LENGTH > out_len) {
388       FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
389         "out_len is less than SHA256_DIGEST_LENGTH");
390       return eFrameworkunifiedStatusInvldParam;
391     }
392     memcpy(out, in, SHA256_DIGEST_LENGTH);
393     *true_length = SHA256_DIGEST_LENGTH;
394   } else {
395     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
396       "the cipher_type isn't support, cipher_type:%d", pcipher_context->cipher_type);
397     return eFrameworkunifiedStatusInvldParam;
398   }
399
400   return eFrameworkunifiedStatusOK;
401 }
402
403 // Decrypt the final ciphertext information
404 EFrameworkunifiedStatus DecryptFinish(void* ctx, uint8_t* out, uint32_t out_len, uint32_t* true_length) {
405   if (NULL == ctx) {
406     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "ctx is NULL");
407     return eFrameworkunifiedStatusInvldParam;
408   }
409   CipherContext* pcipher_context = reinterpret_cast<CipherContext*>(ctx);
410   if (SYMMETRIC_CIPHER_AES == pcipher_context->cipher_type) {  // symmetric encrypt
411     if (NULL == out || NULL == true_length) {
412       FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
413         "out or true_length is NULL, out:%p true_length:%p", out, true_length);
414       return eFrameworkunifiedStatusInvldParam;
415     }
416     uint32_t block_size = pcipher_context->cipher_parameter.symmetric.block_size;
417     if (out_len < block_size) {
418       FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "out_len is less than block_size");
419       return eFrameworkunifiedStatusInvldParam;
420     }
421     if (true == pcipher_context->cipher_parameter.symmetric.to_pad) {
422       // Padding on, the true_length is equal to block_size - padding_length. Because security_hal
423       // is stub implement, padding_length is unknown. Set true_length to 0.
424       *true_length = 0;
425     } else {
426       // Padding off, true_length is equal to 0.
427       *true_length = 0;
428     }
429   } else if (ASYMMETRIC_CIPHER_RSA == pcipher_context->cipher_type) {
430     // EncryptFinish is useless for RSA asymmetric decrypt. So do nothing.
431   } else {
432     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
433       "the cipher_type isn't support, cipher_type:%d", pcipher_context->cipher_type);
434     return eFrameworkunifiedStatusInvldParam;
435   }
436   return eFrameworkunifiedStatusOK;
437 }
438
439 // Clean up decrypt context information
440 EFrameworkunifiedStatus DecryptCleanup(void* ctx) {
441   if (NULL == ctx) {
442     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "ctx is NULL");
443     return eFrameworkunifiedStatusInvldParam;
444   }
445   memset(ctx, 0, sizeof(CipherContext));
446   free(ctx);
447   return eFrameworkunifiedStatusOK;
448 }
449
450 // Initialize hash context information
451 EFrameworkunifiedStatus HashStart(enum HashType hash_type, void** ctx) {
452   if (HASH_TYPE_MD5 > hash_type || HASH_TYPE_SHA512 < hash_type) {
453     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "the hash_type isn't support");
454     return eFrameworkunifiedStatusInvldParam;
455   }
456   if (NULL == ctx) {
457     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "ctx is NULL");
458     return eFrameworkunifiedStatusInvldParam;
459   }
460   void* ctx_temp = malloc(sizeof(HashContext));
461   if (NULL == ctx_temp) {
462     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Failed to malloc %lu byte for ctx, errno=%d",
463            sizeof(HashContext), errno);
464     return eFrameworkunifiedStatusFail;
465   }
466   memset(ctx_temp, 0, sizeof(HashContext));
467   HashContext* phash_context = reinterpret_cast<HashContext*>(ctx_temp);
468   phash_context->hash_type = hash_type;
469   *ctx = ctx_temp;
470   return eFrameworkunifiedStatusOK;
471 }
472
473 // Caculate hash value of input data
474 EFrameworkunifiedStatus HashUpdate(void* ctx, const uint8_t* in, uint32_t in_len) {
475   if (NULL == ctx || NULL == in) {
476     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "ctx or in is NULL, ctx:%p in:%p", ctx, in);
477     return eFrameworkunifiedStatusInvldParam;
478   }
479   if (0 == in_len) {
480     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "in_len is equal to 0");
481     return eFrameworkunifiedStatusInvldParam;
482   }
483   return eFrameworkunifiedStatusOK;
484 }
485
486 // Caculate final message digest
487 EFrameworkunifiedStatus HashFinish(void* ctx, uint8_t* out, uint32_t out_len, uint32_t* true_length) {
488   if (NULL == ctx || NULL == out || NULL == true_length) {
489     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
490       "ctx, out or true_length is NULL, ctx:%p out:%p true_length:%p",
491       ctx, out, true_length);
492     return eFrameworkunifiedStatusInvldParam;
493   }
494   HashContext* phash_context = reinterpret_cast<HashContext*>(ctx);
495   uint32_t digest_length = 0;
496   switch (phash_context->hash_type) {
497     case HASH_TYPE_MD5:
498       digest_length = HASH_TYPE_MD5;
499       break;
500     case HASH_TYPE_SHA1:
501       digest_length = SHA1_DIGEST_LENGTH;
502       break;
503     case HASH_TYPE_SHA224:
504       digest_length = SHA224_DIGEST_LENGTH;
505       break;
506     case HASH_TYPE_SHA256:
507       digest_length = SHA256_DIGEST_LENGTH;
508       break;
509     case HASH_TYPE_SHA384:
510       digest_length = SHA384_DIGEST_LENGTH;
511       break;
512     case HASH_TYPE_SHA512:
513       digest_length = SHA512_DIGEST_LENGTH;
514       break;
515     default:
516       FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
517         "the hash_type isn't support, hash_type:%d", phash_context->hash_type);
518       return eFrameworkunifiedStatusInvldParam;
519   }
520   if (out_len < digest_length) {
521     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "out_len is less than %u", digest_length);
522     return eFrameworkunifiedStatusInvldParam;
523   }
524   memset(out, 0x00, digest_length);
525   *true_length = digest_length;
526   return eFrameworkunifiedStatusOK;
527 }
528
529 // Clean up hash context information
530 EFrameworkunifiedStatus HashCleanup(void* ctx) {
531   if (NULL == ctx) {
532     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "ctx is NULL");
533     return eFrameworkunifiedStatusInvldParam;
534   }
535   memset(ctx, 0, sizeof(HashContext));
536   free(ctx);
537   return eFrameworkunifiedStatusOK;
538 }
539
540 // Initialize random number context information
541 EFrameworkunifiedStatus RandomInit(void** ctx, uint8_t* seed_buffer, uint32_t buffer_len) {
542   if (NULL == ctx || NULL == seed_buffer) {
543     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
544       "ctx or seed_buffer is NULL, ctx:%p seed_buffer:%p", ctx, seed_buffer);
545     return eFrameworkunifiedStatusInvldParam;
546   }
547   if (0 == buffer_len) {
548     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "buffer_len is equal to 0");
549     return eFrameworkunifiedStatusInvldParam;
550   }
551   void* ctx_temp = malloc(sizeof(RandomContext));
552   if (NULL == ctx_temp) {
553     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Failed to malloc %lu byte for ctx, errno=%d",
554            sizeof(RandomContext), errno);
555     return eFrameworkunifiedStatusFail;
556   }
557   memset(ctx_temp, 0, sizeof(RandomContext));
558   RandomContext* prandom_context = reinterpret_cast<RandomContext*>(ctx_temp);
559   prandom_context->seed_buffer = reinterpret_cast<uint8_t*>(malloc(buffer_len));
560   if (NULL == prandom_context->seed_buffer) {
561     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "Failed to malloc %d byte for seed_buffer, errno=%d",
562            buffer_len, errno);
563     free(ctx_temp);
564     ctx_temp = NULL;
565     return eFrameworkunifiedStatusFail;
566   }
567   memcpy(prandom_context->seed_buffer, seed_buffer, buffer_len);
568   prandom_context->buffer_len = buffer_len;
569   *ctx = ctx_temp;
570   return eFrameworkunifiedStatusOK;
571 }
572
573 // Get random number
574 EFrameworkunifiedStatus RandomGet(void* ctx, uint8_t* out, uint32_t out_len, uint32_t* true_length) {
575   if (NULL == ctx || NULL == out || NULL == true_length) {
576     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
577       "ctx, out or true_length is NULL, ctx:%p out:%p true_length:%p",
578       ctx, out, true_length);
579     return eFrameworkunifiedStatusInvldParam;
580   }
581   if (0 == out_len) {
582     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "out_len is equal to 0");
583     return eFrameworkunifiedStatusInvldParam;
584   }
585   // Because security_hal is stub implement, don't assignment value to out or true_length.
586   return eFrameworkunifiedStatusOK;
587 }
588
589 // Clean up random number context information
590 EFrameworkunifiedStatus RandomCleanup(void* ctx) {
591   if (NULL == ctx) {
592     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "ctx is NULL");
593     return eFrameworkunifiedStatusInvldParam;
594   }
595   RandomContext* prandom_context;
596   prandom_context = reinterpret_cast<RandomContext*>(ctx);
597   if (NULL != prandom_context->seed_buffer) {
598     memset(prandom_context->seed_buffer, 0, prandom_context->buffer_len);
599     free(prandom_context->seed_buffer);
600     prandom_context->seed_buffer = NULL;
601   }
602   memset(prandom_context, 0, sizeof(RandomContext));
603   free(prandom_context);
604   prandom_context = NULL;
605   return eFrameworkunifiedStatusOK;
606 }
607
608 // Reset Security IC
609 EFrameworkunifiedStatus ResetSecurityIC(void) {
610   /*
611    *  Note.
612    *  This feature needs to be implemented by the vendor.
613    */
614   return eFrameworkunifiedStatusOK;
615 }