1 /*
2 * Copyright (C) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "adaptor_algorithm.h"
17 #include <openssl/evp.h>
18 #include <openssl/hmac.h>
19 #include <openssl/rand.h>
20 #include <openssl/kdf.h>
21 #include <openssl/sha.h>
22 #include "securec.h"
23 #include "adaptor_log.h"
24 #include "adaptor_memory.h"
25 #include "buffer.h"
26 #include "defines.h"
27
28 #define OPENSSL_SUCCESS 1
29
30 #define ED25519_FIX_PRIKEY_BUFFER_SIZE 32
31 #define ED25519_FIX_PUBKEY_BUFFER_SIZE 32
32
33 #define SHA512_DIGEST_SIZE 64
34 #define NO_PADDING 0
35
CreateEd25519KeyPair(void)36 static KeyPair *CreateEd25519KeyPair(void)
37 {
38 KeyPair *keyPair = Malloc(sizeof(KeyPair));
39 if (keyPair == NULL) {
40 LOG_ERROR("no memory for key pair");
41 return NULL;
42 }
43 keyPair->pubKey = CreateBufferBySize(ED25519_FIX_PUBKEY_BUFFER_SIZE);
44 if (keyPair->pubKey == NULL) {
45 LOG_ERROR("no memory for pub key");
46 Free(keyPair);
47 return NULL;
48 }
49 keyPair->priKey = CreateBufferBySize(ED25519_FIX_PRIKEY_BUFFER_SIZE);
50 if (keyPair->priKey == NULL) {
51 LOG_ERROR("no memory for pri key");
52 DestoryBuffer(keyPair->pubKey);
53 Free(keyPair);
54 return NULL;
55 }
56 return keyPair;
57 }
58
DestoryKeyPair(KeyPair * keyPair)59 void DestoryKeyPair(KeyPair *keyPair)
60 {
61 if (keyPair == NULL) {
62 return;
63 }
64 if (keyPair->pubKey != NULL) {
65 DestoryBuffer(keyPair->pubKey);
66 }
67 if (keyPair->priKey != NULL) {
68 DestoryBuffer(keyPair->priKey);
69 }
70 Free(keyPair);
71 }
72
IsEd25519KeyPairValid(const KeyPair * keyPair)73 bool IsEd25519KeyPairValid(const KeyPair *keyPair)
74 {
75 if (keyPair == NULL) {
76 LOG_ERROR("invalid key pair");
77 return false;
78 }
79 if (!CheckBufferWithSize(keyPair->pubKey, ED25519_FIX_PUBKEY_BUFFER_SIZE)) {
80 LOG_ERROR("invalid pub key");
81 return false;
82 }
83 if (!CheckBufferWithSize(keyPair->priKey, ED25519_FIX_PRIKEY_BUFFER_SIZE)) {
84 LOG_ERROR("invalid pri key");
85 return false;
86 }
87 return true;
88 }
89
GenerateEd25519KeyPair(void)90 KeyPair *GenerateEd25519KeyPair(void)
91 {
92 KeyPair *keyPair = CreateEd25519KeyPair();
93 if (keyPair == NULL) {
94 LOG_ERROR("create key pair fail");
95 return NULL;
96 }
97 EVP_PKEY *key = NULL;
98 EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_ED25519, NULL);
99 if (ctx == NULL) {
100 LOG_ERROR("new ctx fail");
101 goto ERROR;
102 }
103 if (EVP_PKEY_keygen_init(ctx) != OPENSSL_SUCCESS) {
104 LOG_ERROR("init ctx fail");
105 goto ERROR;
106 }
107 if (EVP_PKEY_keygen(ctx, &key) != OPENSSL_SUCCESS) {
108 LOG_ERROR("generate key fail");
109 goto ERROR;
110 }
111 size_t pubKeySize = keyPair->pubKey->maxSize;
112 if (EVP_PKEY_get_raw_public_key(key, keyPair->pubKey->buf, &pubKeySize) != OPENSSL_SUCCESS) {
113 LOG_ERROR("get pub key fail");
114 goto ERROR;
115 }
116 keyPair->pubKey->contentSize = pubKeySize;
117 size_t priKeySize = keyPair->priKey->maxSize;
118 if (EVP_PKEY_get_raw_private_key(key, keyPair->priKey->buf, &priKeySize) != OPENSSL_SUCCESS) {
119 LOG_ERROR("get pri key fail");
120 goto ERROR;
121 }
122 keyPair->priKey->contentSize = priKeySize;
123 goto EXIT;
124
125 ERROR:
126 DestoryKeyPair(keyPair);
127 keyPair = NULL;
128 EXIT:
129 if (key != NULL) {
130 EVP_PKEY_free(key);
131 }
132 if (ctx != NULL) {
133 EVP_PKEY_CTX_free(ctx);
134 }
135 return keyPair;
136 }
137
Ed25519Sign(const KeyPair * keyPair,const Buffer * data,Buffer ** sign)138 int32_t Ed25519Sign(const KeyPair *keyPair, const Buffer *data, Buffer **sign)
139 {
140 if (!IsEd25519KeyPairValid(keyPair) || !IsBufferValid(data) || sign == NULL) {
141 LOG_ERROR("bad param");
142 return RESULT_BAD_PARAM;
143 }
144 int32_t ret = RESULT_GENERAL_ERROR;
145 EVP_PKEY *key = EVP_PKEY_new_raw_private_key(EVP_PKEY_ED25519, NULL,
146 keyPair->priKey->buf, keyPair->priKey->contentSize);
147 if (key == NULL) {
148 LOG_ERROR("get pri key fail");
149 return ret;
150 }
151 EVP_MD_CTX *ctx = EVP_MD_CTX_new();
152 if (ctx == NULL) {
153 LOG_ERROR("get ctx fail");
154 EVP_PKEY_free(key);
155 return ret;
156 }
157 if (EVP_DigestSignInit(ctx, NULL, NULL, NULL, key) != OPENSSL_SUCCESS) {
158 LOG_ERROR("init sign fail");
159 goto EXIT;
160 }
161 *sign = CreateBufferBySize(ED25519_FIX_SIGN_BUFFER_SIZE);
162 if (!IsBufferValid(*sign)) {
163 LOG_ERROR("create buffer fail");
164 goto EXIT;
165 }
166 size_t signSize = (*sign)->maxSize;
167 if (EVP_DigestSign(ctx, (*sign)->buf, &signSize, data->buf, data->contentSize) != OPENSSL_SUCCESS) {
168 LOG_ERROR("sign fail");
169 DestoryBuffer(*sign);
170 *sign = NULL;
171 goto EXIT;
172 }
173 (*sign)->contentSize = signSize;
174 ret = RESULT_SUCCESS;
175
176 EXIT:
177 EVP_PKEY_free(key);
178 EVP_MD_CTX_free(ctx);
179 return ret;
180 }
181
Ed25519Verify(const Buffer * pubKey,const Buffer * data,const Buffer * sign)182 int32_t Ed25519Verify(const Buffer *pubKey, const Buffer *data, const Buffer *sign)
183 {
184 if (!CheckBufferWithSize(pubKey, ED25519_FIX_PUBKEY_BUFFER_SIZE) || !IsBufferValid(data) ||
185 !CheckBufferWithSize(sign, ED25519_FIX_SIGN_BUFFER_SIZE)) {
186 LOG_ERROR("bad param");
187 return RESULT_BAD_PARAM;
188 }
189 int32_t ret = RESULT_GENERAL_ERROR;
190 EVP_PKEY *key = EVP_PKEY_new_raw_public_key(EVP_PKEY_ED25519, NULL, pubKey->buf, pubKey->contentSize);
191 if (key == NULL) {
192 LOG_ERROR("get pub key fail");
193 return ret;
194 }
195 EVP_MD_CTX *ctx = EVP_MD_CTX_new();
196 if (ctx == NULL) {
197 LOG_ERROR("get ctx fail");
198 EVP_PKEY_free(key);
199 return ret;
200 }
201 if (EVP_DigestVerifyInit(ctx, NULL, NULL, NULL, key) != OPENSSL_SUCCESS) {
202 LOG_ERROR("init verify fail");
203 goto EXIT;
204 }
205 if (EVP_DigestVerify(ctx, sign->buf, sign->contentSize, data->buf, data->contentSize) != OPENSSL_SUCCESS) {
206 LOG_ERROR("verify fail");
207 goto EXIT;
208 }
209 ret = RESULT_SUCCESS;
210
211 EXIT:
212 EVP_PKEY_free(key);
213 EVP_MD_CTX_free(ctx);
214 return ret;
215 }
216
IamHmac(const EVP_MD * alg,const Buffer * hmacKey,const Buffer * data,Buffer * hmac)217 static int32_t IamHmac(const EVP_MD *alg,
218 const Buffer *hmacKey, const Buffer *data, Buffer *hmac)
219 {
220 if (!IsBufferValid(hmacKey) || hmacKey->contentSize > INT_MAX ||
221 !IsBufferValid(data) || !IsBufferValid(hmac) || hmac->maxSize > UINT_MAX) {
222 LOG_ERROR("bad param");
223 return RESULT_BAD_PARAM;
224 }
225 unsigned int hmacSize = hmac->maxSize;
226 uint8_t *hmacData = HMAC(alg, hmacKey->buf, (int)hmacKey->contentSize, data->buf, data->contentSize,
227 hmac->buf, &hmacSize);
228 if (hmacData == NULL) {
229 LOG_ERROR("hmac fail");
230 return RESULT_GENERAL_ERROR;
231 }
232 hmac->contentSize = hmacSize;
233 return RESULT_SUCCESS;
234 }
235
HmacSha256(const Buffer * hmacKey,const Buffer * data,Buffer ** hmac)236 int32_t HmacSha256(const Buffer *hmacKey, const Buffer *data, Buffer **hmac)
237 {
238 const EVP_MD *alg = EVP_sha256();
239 if (alg == NULL) {
240 LOG_ERROR("no algo");
241 return RESULT_GENERAL_ERROR;
242 }
243 *hmac = CreateBufferBySize(SHA256_DIGEST_SIZE);
244 if (*hmac == NULL) {
245 LOG_ERROR("create buffer fail");
246 return RESULT_NO_MEMORY;
247 }
248 if (IamHmac(alg, hmacKey, data, *hmac) != RESULT_SUCCESS) {
249 DestoryBuffer(*hmac);
250 *hmac = NULL;
251 LOG_ERROR("hmac fail");
252 return RESULT_GENERAL_ERROR;
253 }
254 return RESULT_SUCCESS;
255 }
256
HmacSha512(const Buffer * hmacKey,const Buffer * data,Buffer ** hmac)257 int32_t HmacSha512(const Buffer *hmacKey, const Buffer *data, Buffer **hmac)
258 {
259 const EVP_MD *alg = EVP_sha512();
260 if (alg == NULL) {
261 LOG_ERROR("no algo");
262 return RESULT_GENERAL_ERROR;
263 }
264 *hmac = CreateBufferBySize(SHA512_DIGEST_SIZE);
265 if (*hmac == NULL) {
266 LOG_ERROR("create buffer fail");
267 return RESULT_NO_MEMORY;
268 }
269 if (IamHmac(alg, hmacKey, data, *hmac) != RESULT_SUCCESS) {
270 DestoryBuffer(*hmac);
271 *hmac = NULL;
272 LOG_ERROR("hmac fail");
273 return RESULT_GENERAL_ERROR;
274 }
275 return RESULT_SUCCESS;
276 }
277
SecureRandom(uint8_t * buffer,uint32_t size)278 int32_t SecureRandom(uint8_t *buffer, uint32_t size)
279 {
280 if (buffer == NULL || size > INT_MAX) {
281 LOG_ERROR("bad param");
282 return RESULT_BAD_PARAM;
283 }
284 if (RAND_bytes(buffer, (int)size) != OPENSSL_SUCCESS) {
285 LOG_ERROR("rand fail");
286 return RESULT_GENERAL_ERROR;
287 }
288 return RESULT_SUCCESS;
289 }
290
SetAesEncryptVi(EVP_CIPHER_CTX * ctx,const Buffer * vi)291 static int32_t SetAesEncryptVi(EVP_CIPHER_CTX *ctx, const Buffer *vi)
292 {
293 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, vi->contentSize, NULL) != OPENSSL_SUCCESS) {
294 LOG_ERROR("failed to set vi len");
295 return RESULT_GENERAL_ERROR;
296 }
297 if (EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, vi->buf) != OPENSSL_SUCCESS) {
298 LOG_ERROR("failed to init vi");
299 return RESULT_GENERAL_ERROR;
300 }
301 return RESULT_SUCCESS;
302 }
303
CreateCiphertext(EVP_CIPHER_CTX * ctx,const Buffer * plaintext)304 static Buffer *CreateCiphertext(EVP_CIPHER_CTX *ctx, const Buffer *plaintext)
305 {
306 Buffer *ciphertext = CreateBufferBySize(plaintext->contentSize);
307 if (!IsBufferValid(ciphertext)) {
308 LOG_ERROR("ciphertext is invalid");
309 return NULL;
310 }
311 if (EVP_CIPHER_CTX_set_padding(ctx, NO_PADDING) != OPENSSL_SUCCESS) {
312 LOG_ERROR("failed to set padding");
313 DestoryBuffer(ciphertext);
314 return NULL;
315 }
316 int32_t outLen = 0;
317 if (EVP_EncryptUpdate(ctx, (unsigned char *)(ciphertext->buf), &outLen,
318 (unsigned char *)plaintext->buf, plaintext->contentSize) != OPENSSL_SUCCESS) {
319 LOG_ERROR("failed to update");
320 DestoryBuffer(ciphertext);
321 return NULL;
322 }
323 if (outLen < 0) {
324 LOG_ERROR("outLen out of range");
325 DestoryBuffer(ciphertext);
326 return NULL;
327 }
328 ciphertext->contentSize = (uint32_t)outLen;
329 if (ciphertext->maxSize < ciphertext->contentSize) {
330 LOG_ERROR("memory overflow occurred, please check");
331 DestoryBuffer(ciphertext);
332 return NULL;
333 }
334 if (EVP_EncryptFinal_ex(ctx, NULL, &outLen) != OPENSSL_SUCCESS || outLen != 0) { // no padding no out
335 LOG_ERROR("failed to finish");
336 DestoryBuffer(ciphertext);
337 return NULL;
338 }
339 return ciphertext;
340 }
341
SpliceOutput(const Buffer * vi,const Buffer * tag,const Buffer * ciphertext,Buffer * cipherInfo)342 static int32_t SpliceOutput(const Buffer *vi, const Buffer *tag, const Buffer *ciphertext, Buffer *cipherInfo)
343 {
344 if (cipherInfo->contentSize != 0) {
345 LOG_ERROR("cipherInfo is not 0 bytes");
346 return RESULT_BAD_PARAM;
347 }
348 if (cipherInfo->maxSize < ciphertext->contentSize ||
349 cipherInfo->maxSize - ciphertext->contentSize < vi->contentSize + tag->contentSize) {
350 LOG_ERROR("bad param");
351 return RESULT_BAD_PARAM;
352 }
353 if (memcpy_s(cipherInfo->buf, cipherInfo->maxSize, vi->buf, vi->contentSize) != EOK) {
354 LOG_ERROR("failed to copy vi");
355 return RESULT_BAD_COPY;
356 }
357 cipherInfo->contentSize += vi->contentSize;
358 if (memcpy_s(cipherInfo->buf + cipherInfo->contentSize, cipherInfo->maxSize - cipherInfo->contentSize,
359 tag->buf, tag->contentSize) != EOK) {
360 LOG_ERROR("failed to copy tag");
361 return RESULT_BAD_COPY;
362 }
363 cipherInfo->contentSize += tag->contentSize;
364 if (memcpy_s(cipherInfo->buf + cipherInfo->contentSize, cipherInfo->maxSize - cipherInfo->contentSize,
365 ciphertext->buf, ciphertext->contentSize) != EOK) {
366 LOG_ERROR("failed to copy ciphertext");
367 return RESULT_BAD_COPY;
368 }
369 cipherInfo->contentSize += ciphertext->contentSize;
370 return RESULT_SUCCESS;
371 }
372
DoAes256GcmEncryptNoPadding(const Buffer * plaintext,const Buffer * key,Buffer * cipherInfo)373 static int32_t DoAes256GcmEncryptNoPadding(const Buffer *plaintext, const Buffer *key, Buffer *cipherInfo)
374 {
375 EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
376 Buffer *vi = CreateBufferBySize(AES_GCM_VI_SIZE);
377 Buffer *tag = CreateBufferBySize(AES_GCM_TAG_SIZE);
378 Buffer *ciphertext = NULL;
379 if (ctx == NULL || !IsBufferValid(vi) || !IsBufferValid(tag)) {
380 LOG_ERROR("failed to init");
381 goto FAIL;
382 }
383 vi->contentSize = AES_GCM_VI_SIZE;
384 if (SecureRandom(vi->buf, vi->contentSize) != RESULT_SUCCESS ||
385 EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, (unsigned char *)key->buf, NULL) != OPENSSL_SUCCESS ||
386 SetAesEncryptVi(ctx, vi) != RESULT_SUCCESS) {
387 LOG_ERROR("failed to call algorithm interface");
388 goto FAIL;
389 }
390 ciphertext = CreateCiphertext(ctx, plaintext);
391 if (!IsBufferValid(ciphertext)) {
392 LOG_ERROR("failed to create ciphertext");
393 goto FAIL;
394 }
395 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, AES_GCM_TAG_SIZE, tag->buf) != OPENSSL_SUCCESS) {
396 LOG_ERROR("failed to get tag");
397 goto FAIL;
398 }
399 tag->contentSize = AES_GCM_TAG_SIZE;
400 if (SpliceOutput(vi, tag, ciphertext, cipherInfo) != RESULT_SUCCESS) {
401 LOG_ERROR("failed to splice");
402 goto FAIL;
403 }
404 DestoryBuffer(vi);
405 DestoryBuffer(ciphertext);
406 DestoryBuffer(tag);
407 EVP_CIPHER_CTX_free(ctx);
408 return RESULT_SUCCESS;
409 FAIL:
410 DestoryBuffer(vi);
411 DestoryBuffer(ciphertext);
412 DestoryBuffer(tag);
413 if (ctx != NULL) {
414 EVP_CIPHER_CTX_free(ctx);
415 }
416 return RESULT_GENERAL_ERROR;
417 }
418
419 // Return is 12 byte VI, 16 byte tag, and the AES ciphertext corresponding to plaintext, is used to parse plaintext.
Aes256GcmEncryptNoPadding(const Buffer * plaintext,const Buffer * key)420 Buffer *Aes256GcmEncryptNoPadding(const Buffer *plaintext, const Buffer *key)
421 {
422 if (!IsBufferValid(plaintext) || plaintext->contentSize == 0 || plaintext->contentSize > CIPHER_INFO_MAX_SIZE ||
423 plaintext->contentSize % AES256_BLOCK_SIZE != 0 || !IsBufferValid(key) || key->contentSize != AES256_KEY_SIZE) {
424 LOG_ERROR("bad param");
425 return NULL;
426 }
427 Buffer *cipherInfo = CreateBufferBySize(CIPHER_INFO_MAX_SIZE);
428 if (!IsBufferValid(cipherInfo)) {
429 LOG_ERROR("failed to create cipherInfo");
430 return NULL;
431 }
432 if (DoAes256GcmEncryptNoPadding(plaintext, key, cipherInfo) != RESULT_SUCCESS) {
433 LOG_ERROR("failed to encrypt");
434 DestoryBuffer(cipherInfo);
435 return NULL;
436 }
437 return cipherInfo;
438 }
439
SplitInput(const Buffer * cipherInfo,Buffer * vi,Buffer * tag,Buffer * ciphertext)440 static int32_t SplitInput(const Buffer *cipherInfo, Buffer *vi, Buffer *tag, Buffer *ciphertext)
441 {
442 if (cipherInfo->contentSize <= AES_GCM_VI_SIZE + AES_GCM_TAG_SIZE ||
443 cipherInfo->contentSize - (AES_GCM_VI_SIZE + AES_GCM_TAG_SIZE) > ciphertext->maxSize) {
444 LOG_ERROR("bad param");
445 return RESULT_BAD_PARAM;
446 }
447 uint32_t offset = 0;
448 if (memcpy_s(vi->buf, vi->maxSize, cipherInfo->buf, AES_GCM_VI_SIZE) != EOK) {
449 LOG_ERROR("failed to copy vi");
450 return RESULT_BAD_COPY;
451 }
452 vi->contentSize = AES_GCM_VI_SIZE;
453 offset += AES_GCM_VI_SIZE;
454 if (memcpy_s(tag->buf, tag->maxSize, cipherInfo->buf + offset, AES_GCM_TAG_SIZE) != EOK) {
455 LOG_ERROR("failed to copy tag");
456 return RESULT_BAD_COPY;
457 }
458 tag->contentSize = AES_GCM_TAG_SIZE;
459 offset += AES_GCM_TAG_SIZE;
460 if (memcpy_s(ciphertext->buf, ciphertext->maxSize,
461 cipherInfo->buf + offset, cipherInfo->contentSize - offset) != EOK) {
462 LOG_ERROR("failed to copy ciphertext");
463 return RESULT_BAD_COPY;
464 }
465 ciphertext->contentSize = cipherInfo->contentSize - offset;
466 return RESULT_SUCCESS;
467 }
468
SetAesDecryptVi(EVP_CIPHER_CTX * ctx,const Buffer * vi)469 static int32_t SetAesDecryptVi(EVP_CIPHER_CTX *ctx, const Buffer *vi)
470 {
471 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, vi->contentSize, NULL) != OPENSSL_SUCCESS) {
472 LOG_ERROR("failed to set vi len");
473 return RESULT_GENERAL_ERROR;
474 }
475 if (EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, vi->buf) != OPENSSL_SUCCESS) {
476 LOG_ERROR("failed to init vi");
477 return RESULT_GENERAL_ERROR;
478 }
479 return RESULT_SUCCESS;
480 }
481
SetPlaintext(EVP_CIPHER_CTX * ctx,const Buffer * ciphertext,const Buffer * tag,Buffer * plaintext)482 static int32_t SetPlaintext(EVP_CIPHER_CTX *ctx, const Buffer *ciphertext, const Buffer *tag, Buffer *plaintext)
483 {
484 if (EVP_CIPHER_CTX_set_padding(ctx, NO_PADDING) != OPENSSL_SUCCESS) {
485 LOG_ERROR("failed to set padding");
486 return RESULT_GENERAL_ERROR;
487 }
488 int32_t outLen = 0;
489 if (EVP_DecryptUpdate(ctx, (unsigned char *)(plaintext->buf), &outLen,
490 (unsigned char *)ciphertext->buf, ciphertext->contentSize) != OPENSSL_SUCCESS) {
491 LOG_ERROR("failed to update");
492 return RESULT_GENERAL_ERROR;
493 }
494 if (outLen < 0) {
495 LOG_ERROR("outLen out of range");
496 return RESULT_GENERAL_ERROR;
497 }
498 plaintext->contentSize = (uint32_t)outLen;
499 if (plaintext->maxSize < plaintext->contentSize) {
500 LOG_ERROR("memory overflow occurred, please check");
501 return RESULT_GENERAL_ERROR;
502 }
503 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, tag->contentSize, tag->buf) != OPENSSL_SUCCESS) {
504 LOG_ERROR("failed to set tag");
505 return RESULT_GENERAL_ERROR;
506 }
507 if (EVP_DecryptFinal_ex(ctx, NULL, &outLen) != OPENSSL_SUCCESS || outLen != 0) { // no padding no out
508 LOG_ERROR("failed to finish");
509 return RESULT_GENERAL_ERROR;
510 }
511 return RESULT_SUCCESS;
512 }
513
DoAes256GcmDecryptNoPadding(const Buffer * cipherInfo,const Buffer * key,Buffer * plaintext)514 static int32_t DoAes256GcmDecryptNoPadding(const Buffer *cipherInfo, const Buffer *key, Buffer *plaintext)
515 {
516 EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
517 Buffer *vi = CreateBufferBySize(AES_GCM_VI_SIZE);
518 Buffer *tag = CreateBufferBySize(AES_GCM_TAG_SIZE);
519 Buffer *ciphertext = CreateBufferBySize(cipherInfo->contentSize);
520 if (ctx == NULL || !IsBufferValid(vi) || !IsBufferValid(tag) || !IsBufferValid(ciphertext)) {
521 LOG_ERROR("failed to init");
522 goto FAIL;
523 }
524 if (SplitInput(cipherInfo, vi, tag, ciphertext) != RESULT_SUCCESS ||
525 EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, (unsigned char *)key->buf, NULL) != OPENSSL_SUCCESS ||
526 SetAesDecryptVi(ctx, vi) != RESULT_SUCCESS ||
527 SetPlaintext(ctx, ciphertext, tag, plaintext) != RESULT_SUCCESS) {
528 LOG_ERROR("failed to call algorithm interface");
529 goto FAIL;
530 }
531 DestoryBuffer(vi);
532 DestoryBuffer(ciphertext);
533 DestoryBuffer(tag);
534 EVP_CIPHER_CTX_free(ctx);
535 return RESULT_SUCCESS;
536 FAIL:
537 DestoryBuffer(vi);
538 DestoryBuffer(ciphertext);
539 DestoryBuffer(tag);
540 if (ctx != NULL) {
541 EVP_CIPHER_CTX_free(ctx);
542 }
543 return RESULT_GENERAL_ERROR;
544 }
545
Aes256GcmDecryptNoPadding(const Buffer * cipherInfo,const Buffer * key)546 Buffer *Aes256GcmDecryptNoPadding(const Buffer *cipherInfo, const Buffer *key)
547 {
548 if (!IsBufferValid(cipherInfo) || cipherInfo->contentSize <= AES_GCM_VI_SIZE + AES_GCM_TAG_SIZE ||
549 cipherInfo->contentSize > CIPHER_INFO_MAX_SIZE || !IsBufferValid(key) || key->contentSize != AES256_KEY_SIZE) {
550 LOG_ERROR("bad param");
551 return NULL;
552 }
553 Buffer *plaintext = CreateBufferBySize(cipherInfo->contentSize);
554 if (!IsBufferValid(plaintext)) {
555 LOG_ERROR("failed to create cipherInfo");
556 return NULL;
557 }
558 if (DoAes256GcmDecryptNoPadding(cipherInfo, key, plaintext) != RESULT_SUCCESS) {
559 LOG_ERROR("failed to do decrypt");
560 DestoryBuffer(plaintext);
561 return NULL;
562 }
563 return plaintext;
564 }
565
566 // Here is the piling code. The real implementation needs to call the security interface.
DeriveDeviceKey(const Buffer * pinData,const Buffer * secret)567 Buffer *DeriveDeviceKey(const Buffer *pinData, const Buffer *secret)
568 {
569 if (!IsBufferValid(secret) || secret->contentSize != SECRET_SIZE || !IsBufferValid(pinData)) {
570 LOG_ERROR("bad param");
571 return NULL;
572 }
573 return CopyBuffer(secret);
574 }
575
Hkdf(const Buffer * salt,const Buffer * rootKey)576 Buffer *Hkdf(const Buffer *salt, const Buffer *rootKey)
577 {
578 if (!IsBufferValid(salt) || salt->contentSize != HKDF_SALT_SIZE ||
579 !IsBufferValid(rootKey) || rootKey->contentSize != HKDF_KEY_SIZE) {
580 LOG_ERROR("bad param");
581 return NULL;
582 }
583 EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL);
584 if (ctx == NULL) {
585 LOG_ERROR("pctx is null");
586 return NULL;
587 }
588 Buffer *key = CreateBufferBySize(SHA256_DIGEST_SIZE);
589 if (!IsBufferValid(key)) {
590 LOG_ERROR("failed to create buffer");
591 EVP_PKEY_CTX_free(ctx);
592 return NULL;
593 }
594 size_t outLen = SHA256_DIGEST_SIZE;
595 if (EVP_PKEY_derive_init(ctx) != OPENSSL_SUCCESS ||
596 EVP_PKEY_CTX_set_hkdf_md(ctx, EVP_sha256()) != OPENSSL_SUCCESS ||
597 EVP_PKEY_CTX_set1_hkdf_salt(ctx, salt->buf, salt->contentSize) != OPENSSL_SUCCESS ||
598 EVP_PKEY_CTX_set1_hkdf_key(ctx, rootKey->buf, rootKey->contentSize) != OPENSSL_SUCCESS ||
599 EVP_PKEY_derive(ctx, key->buf, &outLen) != OPENSSL_SUCCESS ||
600 outLen > key->maxSize) {
601 LOG_ERROR("failed to call algorithm interface");
602 DestoryBuffer(key);
603 EVP_PKEY_CTX_free(ctx);
604 return NULL;
605 }
606 key->contentSize = outLen;
607 EVP_PKEY_CTX_free(ctx);
608 return key;
609 }
610
Sha256Adaptor(const Buffer * data)611 Buffer *Sha256Adaptor(const Buffer *data)
612 {
613 if (!IsBufferValid(data)) {
614 LOG_ERROR("bad param");
615 return NULL;
616 }
617 Buffer *result = CreateBufferBySize(SHA256_DIGEST_SIZE);
618 if (!IsBufferValid(result)) {
619 LOG_ERROR("failed to create buffer");
620 return NULL;
621 }
622 if (SHA256(data->buf, data->contentSize, result->buf) != result->buf) {
623 LOG_ERROR("failed to do sha256");
624 DestoryBuffer(result);
625 return NULL;
626 }
627 result->contentSize = SHA256_DIGEST_SIZE;
628 return result;
629 }