1# Cryptographic Algorithm Functions 2 3openHiTLS provides functions such as encryption and decryption, signature verification, and hash calculation based on the cryptographic algorithm standard. Provided by algorithm module, the main function interfaces support the default cryptographic algorithm capability for the certificate and TLS module in the openHiTLS system 4 5## Function Specifications 6 7* Encryption and decryption: supports symmetric encryption and decryption based on SM4, AES, and CHACHA20, and asymmetric encryption and decryption based on SM2 and RSA. 8* Signature verification: supports SM2, DSA, ED25519, RSA, and ECDSA. 9* Key exchange: supports SM2, X25519, and ECDH. 10* Key derivation: supports PBKDF2, HKDF, SCRYPT, and KDFTLS12. 11* Integrity algorithm: supports integrity protection based on HMAC. 12* Hash calculation: supports digest calculation based on SM3, SHA2, SHA3, MD5, and SHA1. 13* Random number generation: supports DRBG-HASH, DRBG-CTR, and DRBG-HMAC. 14 15# Examples of Encryption and Decryption 16 17## Symmetric Encryption and Decryption 18 19This function provides encryption and decryption capabilities based on symmetric algorithms. The following uses the SM4-CBC algorithm as an example to describe the sample code for reference. 20 21## Sample Code 22 23```c 24#include <stdio.h> 25#include <stdlib.h> 26#include <stdint.h> 27#include <string.h> 28#include "crypt_eal_cipher.h" // Header file of the interfaces for symmetric encryption and decryption. 29#include "bsl_sal.h" 30#include "bsl_err.h" 31#include "crypt_algid.h" // Algorithm ID list. 32#include "crypt_errno.h" // Error code list. 33 34void *StdMalloc(uint32_t len) { 35 return malloc((size_t)len); 36} 37 38void PrintLastError(void) { 39 const char *file = NULL; 40 uint32_t line = 0; 41 BSL_ERR_GetLastErrorFileLine(&file, &line); // Obtain the name and number of lines of the error file. 42 printf("failed at file %s at line %d\n", file, line); 43} 44 45int main(void) 46{ 47 uint8_t data[10] = {0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x1c, 0x14}; 48 uint8_t iv[16] = {0}; 49 uint8_t key[16] = {0}; 50 uint32_t dataLen = sizeof(data); 51 uint8_t cipherText[100]; 52 uint8_t plainText[100]; 53 uint32_t outTotalLen = 0; 54 uint32_t outLen = sizeof(cipherText); 55 uint32_t cipherTextLen; 56 int32_t ret; 57 58 printf("plain text to be encrypted: "); 59 for (uint32_t i = 0; i < dataLen; i++) { 60 printf("%02x", data[i]); 61 } 62 printf("\n"); 63 64 // Initialize the error code module. 65 BSL_ERR_Init(); 66 67 // Before calling the algorithm APIs, call the **BSL_SAL_CallBack_Ctrl** function to register the **malloc** and **free** functions. Execute this step only once. 68 // If the memory allocation ability of Linux is available, the two functions can be registered using Linux by default. 69 BSL_SAL_CallBack_Ctrl(BSL_SAL_MEM_MALLOC, StdMalloc); 70 BSL_SAL_CallBack_Ctrl(BSL_SAL_MEM_FREE, free); 71 72 // Create a context. 73 CRYPT_EAL_CipherCtx *ctx = CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_SM4_CBC); 74 if (ctx == NULL) { 75 PrintLastError(); 76 BSL_ERR_DeInit(); 77 return 1; 78 } 79 // During initialization, the last input parameter can be **true** or **false**. **true** indicates encryption, and **false** indicates decryption. 80 ret = CRYPT_EAL_CipherInit(ctx, key, sizeof(key), iv, sizeof(iv), true); 81 if (ret != CRYPT_SUCCESS) { 82 printf("error code is %x\n", ret); // Output the error code. You can find the error information in **crypt_errno.h** based on the error code. 83 PrintLastError(); 84 goto EXIT; 85 } 86 // Set the padding mode. 87 ret = CRYPT_EAL_CipherSetPadding(ctx, CRYPT_PADDING_PKCS7); 88 if (ret != CRYPT_SUCCESS) { 89 printf("error code is %x\n", ret); 90 PrintLastError(); 91 goto EXIT; 92 } 93 94 // Enter the data to be calculated. This interface can be called for multiple times. The input value of **outLen** is the length of the ciphertext, and the output value is the amount of processed data. 95 ret = CRYPT_EAL_CipherUpdate(ctx, data, dataLen, cipherText, &outLen); 96 if (ret != CRYPT_SUCCESS) { 97 printf("error code is %x\n", ret); 98 PrintLastError(); 99 goto EXIT; 100 } 101 102 outTotalLen += outLen; 103 outLen = sizeof(cipherText) - outTotalLen; 104 105 ret = CRYPT_EAL_CipherFinal(ctx, cipherText + outTotalLen, &outLen); 106 if (ret != CRYPT_SUCCESS) { 107 printf("error code is %x\n", ret); 108 PrintLastError(); 109 goto EXIT; 110 } 111 112 outTotalLen += outLen; 113 printf("cipher text value is: "); 114 115 for (uint32_t i = 0; i < outTotalLen; i++) { 116 printf("%02x", cipherText[i]); 117 } 118 printf("\n"); 119 120 // Start decryption. 121 cipherTextLen = outTotalLen; 122 outTotalLen = 0; 123 outLen = sizeof(plainText); 124 125 // When initializing the decryption function, set the last input parameter to **false**. 126 ret = CRYPT_EAL_CipherInit(ctx, key, sizeof(key), iv, sizeof(iv), false); 127 if (ret != CRYPT_SUCCESS) { 128 printf("error code is %x\n", ret); 129 PrintLastError(); 130 goto EXIT; 131 } 132 133 //Set the padding mode, which must be the same as that for encryption. 134 ret = CRYPT_EAL_CipherSetPadding(ctx, CRYPT_PADDING_PKCS7); 135 if (ret != CRYPT_SUCCESS) { 136 printf("error code is %x\n", ret); 137 PrintLastError(); 138 goto EXIT; 139 } 140 141 // Enter the ciphertext data. 142 ret = CRYPT_EAL_CipherUpdate(ctx, cipherText, cipherTextLen, plainText, &outLen); 143 if (ret != CRYPT_SUCCESS) { 144 printf("error code is %x\n", ret); 145 PrintLastError(); 146 goto EXIT; 147 } 148 outTotalLen += outLen; 149 outLen = sizeof(plainText) - outTotalLen; 150 151 // Decrypt the last segment of data and remove the filled content. 152 ret = CRYPT_EAL_CipherFinal(ctx, plainText + outTotalLen, &outLen); 153 if (ret != CRYPT_SUCCESS) { 154 printf("error code is %x\n", ret); 155 PrintLastError(); 156 goto EXIT; 157 } 158 159 outTotalLen += outLen; 160 161 printf("decrypted plain text value is: "); 162 for (uint32_t i = 0; i < outTotalLen; i++) { 163 printf("%02x", plainText[i]); 164 } 165 printf("\n"); 166 167 if (outTotalLen != dataLen || memcmp(plainText, data, dataLen) != 0) { 168 printf("plaintext comparison failed\n"); 169 goto EXIT; 170 } 171 printf("pass \n"); 172 173EXIT: 174 CRYPT_EAL_CipherFreeCtx(ctx); 175 BSL_ERR_DeInit(); 176 return ret; 177} 178``` 179 180## Asymmetric Encryption and Decryption 181 182This function provides encryption and decryption capabilities based on asymmetric algorithms. The following uses the SM2 encryption and decryption process as an example to describe the sample code for reference. 183 184## Sample Code 185 186```c 187#include <stdio.h> 188#include <stdlib.h> 189#include <stdint.h> 190#include <string.h> 191#include "crypt_eal_pkey.h" // Header file of the interfaces for asymmetric encryption and decryption. 192#include "bsl_sal.h" 193#include "bsl_err.h" 194#include "crypt_algid.h" 195#include "crypt_errno.h" 196#include "crypt_eal_rand.h" 197#include "crypt_eal_init.h" 198#include "crypt_types.h" 199 200void *StdMalloc(uint32_t len) { 201 return malloc((uint32_t)len); 202} 203void PrintLastError(void) { 204 const char *file = NULL; 205 uint32_t line = 0; 206 BSL_ERR_GetLastErrorFileLine(&file, &line); 207 printf("failed at file %s at line %d\n", file, line); 208} 209 210int main(void) { 211 int32_t ret; 212 BSL_ERR_Init(); // Initialize the error code module. 213 // Before calling the algorithm APIs, call the **BSL_SAL_CallBack_Ctrl** function to register the **malloc** and **free** functions. Execute this step only once. 214 // If the memory allocation ability of Linux is available, the two functions can be registered using Linux by default. 215 BSL_SAL_CallBack_Ctrl(BSL_SAL_MEM_MALLOC, StdMalloc); 216 BSL_SAL_CallBack_Ctrl(BSL_SAL_MEM_FREE, free); 217 ret = CRYPT_EAL_Init(CRYPT_EAL_INIT_CPU | CRYPT_EAL_INIT_PROVIDER); 218 if (ret != CRYPT_SUCCESS) { 219 printf("error code is %x\n", ret); 220 PrintLastError(); 221 goto EXIT; 222 } 223 CRYPT_EAL_PkeyCtx *pkey = NULL; 224 pkey = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); 225 if (pkey == NULL) { 226 PrintLastError(); 227 goto EXIT; 228 } 229 230 // Initialize the random number. 231 ret = CRYPT_EAL_ProviderRandInitCtx(NULL, CRYPT_RAND_SHA256, "provider=default", NULL, 0, NULL); 232 if (ret != CRYPT_SUCCESS) { 233 printf("CRYPT_EAL_RandInit: error code is %x\n", ret); 234 PrintLastError(); 235 goto EXIT; 236 } 237 238 // Generate a key pair. 239 ret = CRYPT_EAL_PkeyGen(pkey); 240 if (ret != CRYPT_SUCCESS) { 241 printf("CRYPT_EAL_PkeyGen: error code is %x\n", ret); 242 PrintLastError(); 243 goto EXIT; 244 } 245 246 // Data to be encrypted. 247 char *data = "test enc data"; 248 uint32_t dataLen = 12; 249 uint8_t ecrypt[125] = {0}; 250 uint32_t ecryptLen = 125; 251 uint8_t dcrypt[125] = {0}; 252 uint32_t dcryptLen = 125; 253 // Encrypt data. 254 ret = CRYPT_EAL_PkeyEncrypt(pkey, data, dataLen, ecrypt, &ecryptLen); 255 if (ret != CRYPT_SUCCESS) { 256 printf("CRYPT_EAL_PkeyEncrypt: error code is %x\n", ret); 257 PrintLastError(); 258 goto EXIT; 259 } 260 261 // Decrypt data. 262 ret = CRYPT_EAL_PkeyDecrypt(pkey, ecrypt, ecryptLen, dcrypt, &dcryptLen); 263 if (ret != CRYPT_SUCCESS) { 264 printf("CRYPT_EAL_PkeyDecrypt: error code is %x\n", ret); 265 PrintLastError(); 266 goto EXIT; 267 } 268 269 if (memcmp(dcrypt, data, dataLen) == 0) { 270 printf("encrypt and decrypt success\n"); 271 } else { 272 ret = -1; 273 } 274EXIT: 275 // Release the context memory. 276 CRYPT_EAL_PkeyFreeCtx(pkey); 277 CRYPT_EAL_RandDeinit(); 278 BSL_ERR_DeInit(); 279 return ret; 280} 281``` 282 283# Example of Signature Verification 284 285## Algorithm Type 286 287This function provides the signature verification capability based on asymmetric algorithms. The following uses SM2 signature verification as an example to describe the sample code for reference. 288 289## Sample Code 290 291```c 292#include <stdio.h> 293#include <stdlib.h> 294#include <stdint.h> 295#include <string.h> 296#include "crypt_eal_pkey.h" // Header file for signature verification. 297#include "bsl_sal.h" 298#include "bsl_err.h" 299#include "crypt_algid.h" 300#include "crypt_errno.h" 301#include "crypt_eal_init.h" 302#include "crypt_eal_rand.h" 303 304void *StdMalloc(uint32_t len) { 305 return malloc((size_t)len); 306} 307 308void PrintLastError(void) { 309 const char *file = NULL; 310 uint32_t line = 0; 311 BSL_ERR_GetLastErrorFileLine(&file, &line);// Obtain the name and number of lines of the error file. 312 printf("failed at file %s at line %d\n", file, line); 313} 314 315int main(void) 316{ 317 int ret; 318 uint8_t userId[32] = {0}; 319 uint8_t key[32] = {0}; 320 uint8_t msg[32] = {0}; 321 uint8_t signBuf[100] = {0}; 322 uint32_t signLen = sizeof(signBuf); 323 CRYPT_EAL_PkeyPrv prv = {0}; 324 CRYPT_EAL_PkeyPub pub = {0}; 325 CRYPT_EAL_PkeyCtx *ctx = NULL; 326 327 BSL_ERR_Init(); // Initialize the error code module. 328 // Before calling the algorithm APIs, call the **BSL_SAL_CallBack_Ctrl** function to register the **malloc** and **free** functions. Execute this step only once. 329 // If the memory allocation ability of Linux is available, the two functions can be registered using Linux by default. 330 BSL_SAL_CallBack_Ctrl(BSL_SAL_MEM_MALLOC, StdMalloc); 331 BSL_SAL_CallBack_Ctrl(BSL_SAL_MEM_FREE, free); 332 ret = CRYPT_EAL_Init(CRYPT_EAL_INIT_CPU | CRYPT_EAL_INIT_PROVIDER); 333 if (ret != CRYPT_SUCCESS) { 334 goto EXIT; 335 } 336 ctx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_SM2); 337 if (ctx == NULL) { 338 goto EXIT; 339 } 340 341 // Set a user ID. 342 ret = CRYPT_EAL_PkeyCtrl(ctx, CRYPT_CTRL_SET_SM2_USER_ID, userId, sizeof(userId)); 343 if (ret != CRYPT_SUCCESS) { 344 printf("error code is %x\n", ret); 345 PrintLastError(); 346 goto EXIT; 347 } 348 349 // Initialize the random number. 350 ret = CRYPT_EAL_ProviderRandInitCtx(NULL, CRYPT_RAND_SHA256, "provider=default", NULL, 0, NULL); 351 if (ret != CRYPT_SUCCESS) { 352 printf("error code is %x\n", ret); 353 PrintLastError(); 354 goto EXIT; 355 } 356 357 // Generate a key pair. 358 ret = CRYPT_EAL_PkeyGen(ctx); 359 if (ret != CRYPT_SUCCESS) { 360 printf("error code is %x\n", ret); 361 PrintLastError(); 362 goto EXIT; 363 } 364 365 // Sign. 366 ret = CRYPT_EAL_PkeySign(ctx, CRYPT_MD_SM3, msg, sizeof(msg), signBuf, &signLen); 367 if (ret != CRYPT_SUCCESS) { 368 printf("error code is %x\n", ret); 369 PrintLastError(); 370 goto EXIT; 371 } 372 373 // Verify the signature. 374 ret = CRYPT_EAL_PkeyVerify(ctx, CRYPT_MD_SM3, msg, sizeof(msg), signBuf, signLen); 375 if (ret != CRYPT_SUCCESS) { 376 printf("error code is %x\n", ret); 377 PrintLastError(); 378 goto EXIT; 379 } 380 381 printf("pass \n"); 382 383EXIT: 384 // Release the context memory. 385 CRYPT_EAL_PkeyFreeCtx(ctx); 386 CRYPT_EAL_RandDeinit(); 387 BSL_ERR_DeInit(); 388 return ret; 389} 390``` 391 392# Example of Key Exchange 393 394## Algorithm Type 395 396This function provides the key exchange capability based on asymmetric algorithms. The following uses ECDH as an example to describe the sample code for reference. 397 398## Sample Code 399 400```c 401#include <stdio.h> 402#include <stdlib.h> 403#include <stdint.h> 404#include <string.h> 405#include "crypt_types.h" 406#include "crypt_eal_pkey.h" // Header file for key exchange. 407#include "bsl_sal.h" 408#include "bsl_err.h" 409#include "crypt_algid.h" 410#include "crypt_errno.h" 411#include "crypt_eal_rand.h" 412#include "crypt_eal_init.h" 413 414void *StdMalloc(uint32_t len) { 415 return malloc((size_t)len); 416} 417 418void PrintLastError(void) { 419 const char *file = NULL; 420 uint32_t line = 0; 421 BSL_ERR_GetLastErrorFileLine(&file, &line); 422 printf("failed at file %s at line %d\n", file, line); 423} 424 425int main(void) 426{ 427 int ret; 428 429 uint8_t prikey[] = 430 {0x7d, 0x7d, 0xc5, 0xf7, 0x1e, 0xb2, 0x9d, 0xda, 0xf8, 0x0d, 0x62, 0x14, 0x63, 0x2e, 0xea, 0xe0, 431 0x3d, 0x90, 0x58, 0xaf, 0x1f, 0xb6, 0xd2, 0x2e, 0xd8, 0x0b, 0xad, 0xb6, 0x2b, 0xc1, 0xa5, 0x34}; 432 uint8_t pubkey[] = 433 {0x04, 0x70, 0x0c, 0x48, 0xf7, 0x7f, 0x56, 0x58, 0x4c, 0x5c, 0xc6, 0x32, 0xca, 0x65, 0x64, 0x0d, 0xb9, 434 0x1b, 0x6b, 0xac, 0xce, 0x3a, 0x4d, 0xf6, 0xb4, 0x2c, 0xe7, 0xcc, 0x83, 0x88, 0x33, 0xd2, 0x87, 435 0xdb, 0x71, 0xe5, 0x09, 0xe3, 0xfd, 0x9b, 0x06, 0x0d, 0xdb, 0x20, 0xba, 0x5c, 0x51, 0xdc, 0xc5, 436 0x94, 0x8d, 0x46, 0xfb, 0xf6, 0x40, 0xdf, 0xe0, 0x44, 0x17, 0x82, 0xca, 0xb8, 0x5f, 0xa4, 0xac}; 437 uint8_t resSharekey[] = 438 {0x46, 0xfc, 0x62, 0x10, 0x64, 0x20, 0xff, 0x01, 0x2e, 0x54, 0xa4, 0x34, 0xfb, 0xdd, 0x2d, 0x25, 439 0xcc, 0xc5, 0x85, 0x20, 0x60, 0x56, 0x1e, 0x68, 0x04, 0x0d, 0xd7, 0x77, 0x89, 0x97, 0xbd, 0x7b}; 440 441 CRYPT_EAL_PkeyPrv prvKey = {0}; 442 CRYPT_EAL_PkeyPub pubKey = {0}; 443 uint32_t shareLen; 444 uint8_t *shareKey; 445 CRYPT_EAL_PkeyCtx *prvCtx = NULL; 446 CRYPT_EAL_PkeyCtx *pubCtx = NULL; 447 CRYPT_PKEY_ParaId id = CRYPT_ECC_NISTP256; 448 449 BSL_ERR_Init(); // Initialize the error code module. 450 // Before calling the algorithm APIs, call the **BSL_SAL_CallBack_Ctrl** function to register the **malloc** and **free** functions. Execute this step only once. 451 // If the memory allocation ability of Linux is available, the two functions can be registered using Linux by default. 452 BSL_SAL_CallBack_Ctrl(BSL_SAL_MEM_MALLOC, StdMalloc); 453 BSL_SAL_CallBack_Ctrl(BSL_SAL_MEM_FREE, free); 454 ret = CRYPT_EAL_Init(CRYPT_EAL_INIT_CPU | CRYPT_EAL_INIT_PROVIDER); 455 if (ret != CRYPT_SUCCESS) { 456 printf("error code is %x\n", ret); 457 goto EXIT; 458 } 459 prvCtx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_ECDH); 460 pubCtx = CRYPT_EAL_PkeyNewCtx(CRYPT_PKEY_ECDH); 461 if (prvCtx == NULL || pubCtx == NULL) { 462 goto EXIT; 463 } 464 465 // Set the curve parameters. 466 ret = CRYPT_EAL_PkeySetParaById(prvCtx, id); 467 if (ret != CRYPT_SUCCESS) { 468 printf("error code is %x\n", ret); 469 PrintLastError(); 470 goto EXIT; 471 } 472 473 // Set the private key of one end. 474 prvKey.id = CRYPT_PKEY_ECDH; 475 prvKey.key.eccPrv.len = sizeof(prikey); 476 prvKey.key.eccPrv.data = prikey; 477 ret = CRYPT_EAL_PkeySetPrv(prvCtx, &prvKey); 478 if (ret != CRYPT_SUCCESS) { 479 printf("error code is %x\n", ret); 480 PrintLastError(); 481 goto EXIT; 482 } 483 484 // Set the curve parameters. 485 ret = CRYPT_EAL_PkeySetParaById(pubCtx, id); 486 if (ret != CRYPT_SUCCESS) { 487 printf("error code is %x\n", ret); 488 PrintLastError(); 489 goto EXIT; 490 } 491 492 // Set the public key of the other end. 493 pubKey.id = CRYPT_PKEY_ECDH; 494 pubKey.key.eccPub.len = sizeof(pubkey); 495 pubKey.key.eccPub.data = pubkey; 496 ret = CRYPT_EAL_PkeySetPub(pubCtx, &pubKey); 497 if (ret != CRYPT_SUCCESS) { 498 printf("error code is %x\n", ret); 499 PrintLastError(); 500 goto EXIT; 501 } 502 503 // The shared key involves only the X axis. The length of the public key is not compressed in the returned results. 504 shareLen = CRYPT_EAL_PkeyGetKeyLen(prvCtx) / 2; 505 shareKey = (uint8_t *)BSL_SAL_Malloc(shareLen); 506 if (shareKey == NULL) { 507 ret = CRYPT_MEM_ALLOC_FAIL; 508 PrintLastError(); 509 goto EXIT; 510 } 511 512 // Initialize the random number. 513 ret = CRYPT_EAL_ProviderRandInitCtx(NULL, CRYPT_RAND_SHA256, "provider=default", NULL, 0, NULL); 514 if (ret != CRYPT_SUCCESS) { 515 printf("CRYPT_EAL_RandInit: error code is %x\n", ret); 516 PrintLastError(); 517 goto EXIT; 518 } 519 520 // Calculate the shared key. 521 ret = CRYPT_EAL_PkeyComputeShareKey(prvCtx, pubCtx, shareKey, &shareLen); 522 if (ret != CRYPT_SUCCESS) { 523 printf("error code is %x\n", ret); 524 PrintLastError(); 525 goto EXIT; 526 } 527 528 // Compare the calculation result with the expected one. 529 if (shareLen != sizeof(resSharekey) || memcmp(shareKey, resSharekey, shareLen) != 0) { 530 printf("failed to compare test results\n"); 531 ret = -1; 532 goto EXIT; 533 } 534 535 printf("pass \n"); 536 537EXIT: 538 // Release the context memory. 539 CRYPT_EAL_RandDeinit(); 540 CRYPT_EAL_PkeyFreeCtx(prvCtx); 541 CRYPT_EAL_PkeyFreeCtx(pubCtx); 542 BSL_SAL_Free(shareKey); 543 BSL_ERR_DeInit(); 544 return 0; 545} 546``` 547 548# Example of Key Derivation 549 550## Algorithm Type 551 552The PBKDF2, HKDF, SCRYPT, and KDFTLS12 algorithms can be used for key derivation. The following uses PBKDF2 as an example to describe the sample code for reference. 553 554## Sample Code 555 556```c 557#include <stdint.h> 558#include <stdlib.h> 559#include <stdio.h> 560#include <string.h> 561#include "crypt_errno.h" 562#include "bsl_sal.h" 563#include "bsl_err.h" 564#include "crypt_algid.h" 565#include "crypt_eal_kdf.h" 566#include "bsl_params.h" 567#include "crypt_params_key.h" 568 569#define PBKDF2_PARAM_LEN (4) 570 571void *StdMalloc(uint32_t len) { 572 return malloc((size_t)len); 573} 574 575void PrintLastError(void) { 576 const char *file = NULL; 577 uint32_t line = 0; 578 BSL_ERR_GetLastErrorFileLine(&file, &line); 579 printf("failed at file %s at line %d\n", file, line); 580} 581 582int main(void) 583{ 584 int32_t ret; 585 uint8_t key[] = {0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64}; 586 uint8_t salt[] = {0x4e, 0x61, 0x43, 0x6c}; 587 uint32_t iterations = 80000; 588 uint8_t result[] = { 589 0x4d, 0xdc, 0xd8, 0xf6, 0x0b, 0x98, 0xbe, 0x21, 590 0x83, 0x0c, 0xee, 0x5e, 0xf2, 0x27, 0x01, 0xf9, 591 0x64, 0x1a, 0x44, 0x18, 0xd0, 0x4c, 0x04, 0x14, 592 0xae, 0xff, 0x08, 0x87, 0x6b, 0x34, 0xab, 0x56, 593 0xa1, 0xd4, 0x25, 0xa1, 0x22, 0x58, 0x33, 0x54, 594 0x9a, 0xdb, 0x84, 0x1b, 0x51, 0xc9, 0xb3, 0x17, 595 0x6a, 0x27, 0x2b, 0xde, 0xbb, 0xa1, 0xd0, 0x78, 596 0x47, 0x8f, 0x62, 0xb3, 0x97, 0xf3, 0x3c, 0x8d}; 597 598 uint8_t out[sizeof(result)] = {0}; 599 uint32_t outLen = sizeof(result); 600 601 // Initialize the error code module. 602 BSL_ERR_Init(); 603 604 /** 605 * Before calling the algorithm APIs, 606 * call the BSL_SAL_CallBack_Ctrl function to register the malloc and free functions. 607 * Execute this step only once. If the memory allocation ability of Linux is available, 608 * the two functions can be registered using Linux by default. 609 */ 610 BSL_SAL_CallBack_Ctrl(BSL_SAL_MEM_MALLOC, StdMalloc); 611 BSL_SAL_CallBack_Ctrl(BSL_SAL_MEM_FREE, free); 612 613 CRYPT_EAL_KdfCTX *ctx = CRYPT_EAL_KdfNewCtx(CRYPT_KDF_PBKDF2); 614 if (ctx == NULL) { 615 PrintLastError(); 616 goto EXIT; 617 } 618 CRYPT_MAC_AlgId id = CRYPT_MAC_HMAC_SHA256; 619 BSL_Param params[5] = {{0}, {0}, {0}, {0}, BSL_PARAM_END}; 620 (void)BSL_PARAM_InitValue(¶ms[0], CRYPT_PARAM_KDF_MAC_ID, BSL_PARAM_TYPE_UINT32, &id, sizeof(id)); 621 (void)BSL_PARAM_InitValue(¶ms[1], CRYPT_PARAM_KDF_PASSWORD, BSL_PARAM_TYPE_OCTETS, key, sizeof(key)); 622 (void)BSL_PARAM_InitValue(¶ms[2], CRYPT_PARAM_KDF_SALT, BSL_PARAM_TYPE_OCTETS, salt, sizeof(salt)); 623 (void)BSL_PARAM_InitValue(¶ms[3], CRYPT_PARAM_KDF_ITER, BSL_PARAM_TYPE_UINT32, &iterations, sizeof(iterations)); 624 ret = CRYPT_EAL_KdfSetParam(ctx, params); 625 if (ret != CRYPT_SUCCESS) { 626 printf("error code is %x\n", ret); 627 PrintLastError(); 628 goto EXIT; 629 } 630 631 ret = CRYPT_EAL_KdfDerive(ctx, out, outLen); 632 if (ret != CRYPT_SUCCESS) { 633 printf("error code is %x\n", ret); 634 PrintLastError(); 635 goto EXIT; 636 } 637 638 if (memcmp(out, result, sizeof(result)) != 0) { 639 printf("failed to compare test results\n"); 640 ret = -1; 641 goto EXIT; 642 } 643 printf("pass \n"); 644 645EXIT: 646 BSL_ERR_DeInit(); 647 CRYPT_EAL_KdfFreeCtx(ctx); 648 return ret; 649} 650``` 651 652# Example of Random Number Generation 653 654## Algorithm Type 655 656The DRBG-SHA, DRBG-HMAC, and DRBG-CTR algorithms can be used for random number generation. The interfaces include global random number interfaces and multi-instance random number interfaces. 657 658```c 659/* 660* Global random number initializing and deinitializing interfaces. 661 * The **seedMeth** value of initializing interfaces is the entropy source of the callback, and the **seedCtx** value is the context called back by the user. 662* Users can set their own entropy source. If it is not set, the default entropy source is used. 663* Currently, entropy can be obtained from **/dev/random** of Linux. 664*/ 665int32_t CRYPT_EAL_RandInit(CRYPT_RAND_AlgId id, CRYPT_RandSeedMethod *seedMeth, void *seedCtx, const uint8_t *pers, uint32_t persLen); 666void CRYPT_EAL_RandDeinit(void); 667 668/* After initialization, users can call the following interfaces to obtain the pseudo-random number and supplement the entropy source.*/ 669int32_t CRYPT_EAL_Randbytes(uint8_t *byte, uint32_t len); 670int32_t CRYPT_EAL_RandSeed(void); 671 672/*The deterministic random bit generator (DRBG) context of the multi-instance random number interfaces is returned to the user. This is the main difference between the two types of interfaces. 673 * Multiple DRBG contexts can be created. Different contexts do not interfere with each other during entropy source setting and internal status change.*/ 674CRYPT_EAL_RndCtx *CRYPT_EAL_DrbgNew(CRYPT_RAND_AlgId id, CRYPT_RandSeedMethod *seedMeth, void *seedCtx); 675void CRYPT_EAL_DrbgDeinit(CRYPT_EAL_RndCtx *ctx); 676``` 677 678The following uses the DRBG-SHA algorithm as an example to describe the sample code for reference. 679 680## Sample Code 681 682```c 683#include <stdio.h> 684#include <stdlib.h> 685#include <stdint.h> 686#include <string.h> 687#include "crypt_types.h" 688#include "bsl_sal.h" 689#include "bsl_err.h" 690#include "crypt_algid.h" 691#include "crypt_errno.h" 692#include "crypt_eal_init.h" 693#include "crypt_eal_rand.h" 694 695void *StdMalloc(uint32_t len) { 696 return malloc((size_t)len); 697} 698 699void PrintLastError(void) { 700 const char *file = NULL; 701 uint32_t line = 0; 702 BSL_ERR_GetLastErrorFileLine(&file, &line); 703 printf("failed at file %s at line %d\n", file, line); 704} 705 706int main(void) 707{ 708 int ret; 709 uint8_t output[100] = {0}; 710 uint32_t len = 100; 711 712 // Before calling the algorithm APIs, call the **BSL_SAL_CallBack_Ctrl** function to register the **malloc** and **free** functions. Execute this step only once. 713 // If the memory allocation ability of Linux is available, the two functions can be registered using Linux by default. 714 BSL_SAL_CallBack_Ctrl(BSL_SAL_MEM_MALLOC, StdMalloc); 715 BSL_SAL_CallBack_Ctrl(BSL_SAL_MEM_FREE, free); 716 717 BSL_ERR_Init();// Initialize the error module. 718 ret = CRYPT_EAL_Init(CRYPT_EAL_INIT_CPU | CRYPT_EAL_INIT_PROVIDER); 719 if (ret != CRYPT_SUCCESS) { 720 printf("error code is %x\n", ret); 721 goto EXIT; 722 } 723 // Initialize the global random number by using the default entropy source from **/dev/random** of Linux. 724 ret = CRYPT_EAL_ProviderRandInitCtx(NULL, CRYPT_RAND_SHA256, "provider=default", NULL, 0, NULL); 725 if (ret != CRYPT_SUCCESS) { 726 printf("CRYPT_EAL_RandInit: error code is %x\n", ret); 727 PrintLastError(); 728 goto EXIT; 729 } 730 731 // Obtain the random number sequence of the **len** value. 732 ret = CRYPT_EAL_RandbytesEx(NULL, output, len); 733 if (ret != CRYPT_SUCCESS) { 734 printf("CRYPT_EAL_Randbytes: error code is %x\n", ret); 735 PrintLastError(); 736 goto EXIT; 737 } 738 739 printf("random value is: "); // Output the random number. 740 for (uint32_t i = 0; i < len; i++) { 741 printf("%02x", output[i]); 742 } 743 printf("\n"); 744 745 // Reseeding 746 ret = CRYPT_EAL_RandSeedEx(NULL); 747 if (ret != CRYPT_SUCCESS) { 748 printf("CRYPT_EAL_RandSeed: error code is %x\n", ret); 749 PrintLastError(); 750 goto EXIT; 751 } 752 753 // Obtain the random number sequence of the **len** value. 754 ret = CRYPT_EAL_RandbytesEx(NULL, output, len); 755 if (ret != CRYPT_SUCCESS) { 756 printf("CRYPT_EAL_Randbytes: error code is %x\n", ret); 757 PrintLastError(); 758 goto EXIT; 759 } 760 761 printf("random value is: "); // Output the random number. 762 for (uint32_t i = 0; i < len; i++) { 763 printf("%02x", output[i]); 764 } 765 printf("\n"); 766 767EXIT: 768 // Release the context memory. 769 CRYPT_EAL_RandDeinit(); 770 BSL_ERR_DeInit(); 771 return 0; 772} 773``` 774