1 // This file was extracted from the TCG Published 2 // Trusted Platform Module Library 3 // Part 4: Supporting Routines 4 // Family "2.0" 5 // Level 00 Revision 01.16 6 // October 30, 2014 7 8 #include "OsslCryptoEngine.h" 9 // 10 // The following sets of defines are used to allow use of the SM4 algorithm identifier while waiting for the 11 // SM4 implementation code to appear. 12 // 13 typedef AES_KEY SM4_KEY; 14 #define SM4_set_encrypt_key AES_set_encrypt_key 15 #define SM4_set_decrypt_key AES_set_decrypt_key 16 #define SM4_decrypt AES_decrypt 17 #define SM4_encrypt AES_encrypt 18 // 19 // 20 // Utility Functions 21 // 22 // _cpri_SymStartup() 23 // 24 LIB_EXPORT BOOL 25 _cpri__SymStartup( 26 void 27 ) 28 { 29 return TRUE; 30 } 31 // 32 // 33 // _cpri__GetSymmetricBlockSize() 34 // 35 // This function returns the block size of the algorithm. 36 // 37 // Return Value Meaning 38 // 39 // <= 0 cipher not supported 40 // >0 the cipher block size in bytes 41 // 42 LIB_EXPORT INT16 43 _cpri__GetSymmetricBlockSize( 44 TPM_ALG_ID symmetricAlg, // IN: the symmetric algorithm 45 UINT16 keySizeInBits // IN: the key size 46 ) 47 { 48 switch (symmetricAlg) 49 { 50 #ifdef TPM_ALG_AES 51 case TPM_ALG_AES: 52 #endif 53 #ifdef TPM_ALG_SM4 // Both AES and SM4 use the same block size 54 case TPM_ALG_SM4: 55 #endif 56 if(keySizeInBits != 0) // This is mostly to have a reference to 57 // keySizeInBits for the compiler 58 return 16; 59 else 60 return 0; 61 break; 62 default: 63 return 0; 64 } 65 } 66 // 67 // 68 // AES Encryption 69 // 70 // _cpri__AESEncryptCBC() 71 // 72 // This function performs AES encryption in CBC chain mode. The input dIn buffer is encrypted into dOut. 73 // The input iv buffer is required to have a size equal to the block size (16 bytes). The dInSize is required to 74 // be a multiple of the block size. 75 // 76 // Return Value Meaning 77 // 78 // CRYPT_SUCCESS if success 79 // CRYPT_PARAMETER dInSize is not a multiple of the block size 80 // 81 LIB_EXPORT CRYPT_RESULT 82 _cpri__AESEncryptCBC( 83 BYTE *dOut, // OUT: 84 UINT32 keySizeInBits, // IN: key size in bit 85 BYTE *key, // IN: key buffer. The size of this buffer in 86 // bytes is (keySizeInBits + 7) / 8 87 BYTE *iv, // IN/OUT: IV for decryption. 88 UINT32 dInSize, // IN: data size (is required to be a multiple 89 // of 16 bytes) 90 BYTE *dIn // IN: data buffer 91 ) 92 { 93 AES_KEY AesKey; 94 BYTE *pIv; 95 INT32 dSize; // Need a signed version 96 int i; 97 pAssert(dOut != NULL && key != NULL && iv != NULL && dIn != NULL); 98 if(dInSize == 0) 99 return CRYPT_SUCCESS; 100 pAssert(dInSize <= INT32_MAX); 101 dSize = (INT32)dInSize; 102 // For CBC, the data size must be an even multiple of the 103 // cipher block size 104 if((dSize % 16) != 0) 105 return CRYPT_PARAMETER; 106 // Create AES encrypt key schedule 107 if (AES_set_encrypt_key(key, keySizeInBits, &AesKey) != 0) 108 FAIL(FATAL_ERROR_INTERNAL); 109 // XOR the data block into the IV, encrypt the IV into the IV 110 // and then copy the IV to the output 111 for(; dSize > 0; dSize -= 16) 112 { 113 pIv = iv; 114 for(i = 16; i > 0; i--) 115 *pIv++ ^= *dIn++; 116 AES_encrypt(iv, iv, &AesKey); 117 pIv = iv; 118 for(i = 16; i > 0; i--) 119 *dOut++ = *pIv++; 120 } 121 return CRYPT_SUCCESS; 122 } 123 // 124 // 125 // _cpri__AESDecryptCBC() 126 // 127 // This function performs AES decryption in CBC chain mode. The input dIn buffer is decrypted into dOut. 128 // The input iv buffer is required to have a size equal to the block size (16 bytes). The dInSize is required to 129 // be a multiple of the block size. 130 // 131 // Return Value Meaning 132 // 133 // CRYPT_SUCCESS if success 134 // CRYPT_PARAMETER dInSize is not a multiple of the block size 135 // 136 LIB_EXPORT CRYPT_RESULT 137 _cpri__AESDecryptCBC( 138 BYTE *dOut, // OUT: the decrypted data 139 UINT32 keySizeInBits, // IN: key size in bit 140 BYTE *key, // IN: key buffer. The size of this buffer in 141 // bytes is (keySizeInBits + 7) / 8 142 BYTE *iv, // IN/OUT: IV for decryption. The size of this 143 // buffer is 16 byte 144 UINT32 dInSize, // IN: data size 145 BYTE *dIn // IN: data buffer 146 ) 147 { 148 AES_KEY AesKey; 149 BYTE *pIv; 150 int i; 151 BYTE tmp[16]; 152 BYTE *pT = NULL; 153 INT32 dSize; 154 pAssert(dOut != NULL && key != NULL && iv != NULL && dIn != NULL); 155 if(dInSize == 0) 156 return CRYPT_SUCCESS; 157 pAssert(dInSize <= INT32_MAX); 158 dSize = (INT32)dInSize; 159 // For CBC, the data size must be an even multiple of the 160 // cipher block size 161 if((dSize % 16) != 0) 162 return CRYPT_PARAMETER; 163 // Create AES key schedule 164 if (AES_set_decrypt_key(key, keySizeInBits, &AesKey) != 0) 165 FAIL(FATAL_ERROR_INTERNAL); 166 // Copy the input data to a temp buffer, decrypt the buffer into the output; 167 // XOR in the IV, and copy the temp buffer to the IV and repeat. 168 for(; dSize > 0; dSize -= 16) 169 { 170 // 171 pT = tmp; 172 for(i = 16; i> 0; i--) 173 *pT++ = *dIn++; 174 AES_decrypt(tmp, dOut, &AesKey); 175 pIv = iv; 176 pT = tmp; 177 for(i = 16; i> 0; i--) 178 { 179 *dOut++ ^= *pIv; 180 *pIv++ = *pT++; 181 } 182 } 183 return CRYPT_SUCCESS; 184 } 185 // 186 // 187 // _cpri__AESEncryptCFB() 188 // 189 // This function performs AES encryption in CFB chain mode. The dOut buffer receives the values 190 // encrypted dIn. The input iv is assumed to be the size of an encryption block (16 bytes). The iv buffer will 191 // be modified to contain the last encrypted block. 192 // 193 // Return Value Meaning 194 // 195 // CRYPT_SUCCESS no non-fatal errors 196 // 197 LIB_EXPORT CRYPT_RESULT 198 _cpri__AESEncryptCFB( 199 BYTE *dOut, // OUT: the encrypted 200 UINT32 keySizeInBits, // IN: key size in bit 201 BYTE *key, // IN: key buffer. The size of this buffer in 202 // bytes is (keySizeInBits + 7) / 8 203 BYTE *iv, // IN/OUT: IV for decryption. 204 UINT32 dInSize, // IN: data size 205 BYTE *dIn // IN: data buffer 206 ) 207 { 208 BYTE *pIv = NULL; 209 AES_KEY AesKey; 210 INT32 dSize; // Need a signed version of dInSize 211 int i; 212 pAssert(dOut != NULL && key != NULL && iv != NULL && dIn != NULL); 213 if(dInSize == 0) 214 return CRYPT_SUCCESS; 215 pAssert(dInSize <= INT32_MAX); 216 dSize = (INT32)dInSize; 217 // Create AES encryption key schedule 218 if (AES_set_encrypt_key(key, keySizeInBits, &AesKey) != 0) 219 FAIL(FATAL_ERROR_INTERNAL); 220 // Encrypt the IV into the IV, XOR in the data, and copy to output 221 for(; dSize > 0; dSize -= 16) 222 { 223 // Encrypt the current value of the IV 224 AES_encrypt(iv, iv, &AesKey); 225 pIv = iv; 226 for(i = (int)(dSize < 16) ? dSize : 16; i > 0; i--) 227 // XOR the data into the IV to create the cipher text 228 // and put into the output 229 *dOut++ = *pIv++ ^= *dIn++; 230 } 231 // If the inner loop (i loop) was smaller than 16, then dSize would have been 232 // smaller than 16 and it is now negative. If it is negative, then it indicates 233 // how many bytes are needed to pad out the IV for the next round. 234 for(; dSize < 0; dSize++) 235 *pIv++ = 0; 236 return CRYPT_SUCCESS; 237 } 238 // 239 // 240 // _cpri__AESDecryptCFB() 241 // 242 // This function performs AES decrypt in CFB chain mode. The dOut buffer receives the values decrypted 243 // from dIn. 244 // The input iv is assumed to be the size of an encryption block (16 bytes). The iv buffer will be modified to 245 // contain the last decoded block, padded with zeros 246 // 247 // Return Value Meaning 248 // 249 // CRYPT_SUCCESS no non-fatal errors 250 // 251 LIB_EXPORT CRYPT_RESULT 252 _cpri__AESDecryptCFB( 253 BYTE *dOut, // OUT: the decrypted data 254 UINT32 keySizeInBits, // IN: key size in bit 255 BYTE *key, // IN: key buffer. The size of this buffer in 256 // bytes is (keySizeInBits + 7) / 8 257 BYTE *iv, // IN/OUT: IV for decryption. 258 UINT32 dInSize, // IN: data size 259 BYTE *dIn // IN: data buffer 260 ) 261 { 262 BYTE *pIv = NULL; 263 BYTE tmp[16]; 264 int i; 265 BYTE *pT; 266 AES_KEY AesKey; 267 INT32 dSize; 268 pAssert(dOut != NULL && key != NULL && iv != NULL && dIn != NULL); 269 if(dInSize == 0) 270 return CRYPT_SUCCESS; 271 pAssert(dInSize <= INT32_MAX); 272 dSize = (INT32)dInSize; 273 // Create AES encryption key schedule 274 if (AES_set_encrypt_key(key, keySizeInBits, &AesKey) != 0) 275 FAIL(FATAL_ERROR_INTERNAL); 276 for(; dSize > 0; dSize -= 16) 277 { 278 // Encrypt the IV into the temp buffer 279 AES_encrypt(iv, tmp, &AesKey); 280 pT = tmp; 281 pIv = iv; 282 for(i = (dSize < 16) ? dSize : 16; i > 0; i--) 283 // Copy the current cipher text to IV, XOR 284 // with the temp buffer and put into the output 285 *dOut++ = *pT++ ^ (*pIv++ = *dIn++); 286 } 287 // If the inner loop (i loop) was smaller than 16, then dSize 288 // would have been smaller than 16 and it is now negative 289 // If it is negative, then it indicates how may fill bytes 290 // are needed to pad out the IV for the next round. 291 for(; dSize < 0; dSize++) 292 *pIv++ = 0; 293 return CRYPT_SUCCESS; 294 } 295 // 296 // 297 // _cpri__AESEncryptCTR() 298 // 299 // This function performs AES encryption/decryption in CTR chain mode. The dIn buffer is encrypted into 300 // dOut. The input iv buffer is assumed to have a size equal to the AES block size (16 bytes). The iv will be 301 // incremented by the number of blocks (full and partial) that were encrypted. 302 // 303 // Return Value Meaning 304 // 305 // CRYPT_SUCCESS no non-fatal errors 306 // 307 LIB_EXPORT CRYPT_RESULT 308 _cpri__AESEncryptCTR( 309 BYTE *dOut, // OUT: the encrypted data 310 UINT32 keySizeInBits, // IN: key size in bit 311 BYTE *key, // IN: key buffer. The size of this buffer in 312 // bytes is (keySizeInBits + 7) / 8 313 BYTE *iv, // IN/OUT: IV for decryption. 314 UINT32 dInSize, // IN: data size 315 BYTE *dIn // IN: data buffer 316 ) 317 { 318 BYTE tmp[16]; 319 BYTE *pT; 320 AES_KEY AesKey; 321 int i; 322 INT32 dSize; 323 pAssert(dOut != NULL && key != NULL && iv != NULL && dIn != NULL); 324 if(dInSize == 0) 325 return CRYPT_SUCCESS; 326 pAssert(dInSize <= INT32_MAX); 327 dSize = (INT32)dInSize; 328 // Create AES encryption schedule 329 if (AES_set_encrypt_key(key, keySizeInBits, &AesKey) != 0) 330 FAIL(FATAL_ERROR_INTERNAL); 331 for(; dSize > 0; dSize -= 16) 332 { 333 // Encrypt the current value of the IV(counter) 334 AES_encrypt(iv, (BYTE *)tmp, &AesKey); 335 //increment the counter (counter is big-endian so start at end) 336 for(i = 15; i >= 0; i--) 337 if((iv[i] += 1) != 0) 338 break; 339 // XOR the encrypted counter value with input and put into output 340 pT = tmp; 341 for(i = (dSize < 16) ? dSize : 16; i > 0; i--) 342 *dOut++ = *dIn++ ^ *pT++; 343 } 344 return CRYPT_SUCCESS; 345 } 346 // 347 // _cpri__AESEncryptECB() 348 // 349 // AES encryption in ECB mode. The data buffer is modified to contain the cipher text. 350 // 351 // Return Value Meaning 352 // 353 // CRYPT_SUCCESS no non-fatal errors 354 // 355 LIB_EXPORT CRYPT_RESULT 356 _cpri__AESEncryptECB( 357 BYTE *dOut, // OUT: encrypted data 358 UINT32 keySizeInBits, // IN: key size in bit 359 BYTE *key, // IN: key buffer. The size of this buffer in 360 // bytes is (keySizeInBits + 7) / 8 361 UINT32 dInSize, // IN: data size 362 BYTE *dIn // IN: clear text buffer 363 ) 364 { 365 AES_KEY AesKey; 366 INT32 dSize; 367 pAssert(dOut != NULL && key != NULL && dIn != NULL); 368 if(dInSize == 0) 369 return CRYPT_SUCCESS; 370 pAssert(dInSize <= INT32_MAX); 371 dSize = (INT32)dInSize; 372 // For ECB, the data size must be an even multiple of the 373 // cipher block size 374 if((dSize % 16) != 0) 375 return CRYPT_PARAMETER; 376 // Create AES encrypting key schedule 377 if (AES_set_encrypt_key(key, keySizeInBits, &AesKey) != 0) 378 FAIL(FATAL_ERROR_INTERNAL); 379 for(; dSize > 0; dSize -= 16) 380 { 381 AES_encrypt(dIn, dOut, &AesKey); 382 dIn = &dIn[16]; 383 dOut = &dOut[16]; 384 } 385 return CRYPT_SUCCESS; 386 } 387 // 388 // 389 // _cpri__AESDecryptECB() 390 // 391 // This function performs AES decryption using ECB (not recommended). The cipher text dIn is decrypted 392 // into dOut. 393 // 394 // Return Value Meaning 395 // 396 // CRYPT_SUCCESS no non-fatal errors 397 // 398 LIB_EXPORT CRYPT_RESULT 399 _cpri__AESDecryptECB( 400 BYTE *dOut, // OUT: the clear text data 401 UINT32 keySizeInBits, // IN: key size in bit 402 BYTE *key, // IN: key buffer. The size of this buffer in 403 // bytes is (keySizeInBits + 7) / 8 404 UINT32 dInSize, // IN: data size 405 BYTE *dIn // IN: cipher text buffer 406 ) 407 { 408 AES_KEY AesKey; 409 INT32 dSize; 410 pAssert(dOut != NULL && key != NULL && dIn != NULL); 411 if(dInSize == 0) 412 return CRYPT_SUCCESS; 413 pAssert(dInSize <= INT32_MAX); 414 dSize = (INT32)dInSize; 415 // For ECB, the data size must be an even multiple of the 416 // cipher block size 417 if((dSize % 16) != 0) 418 return CRYPT_PARAMETER; 419 // Create AES decryption key schedule 420 if (AES_set_decrypt_key(key, keySizeInBits, &AesKey) != 0) 421 FAIL(FATAL_ERROR_INTERNAL); 422 for(; dSize > 0; dSize -= 16) 423 { 424 AES_decrypt(dIn, dOut, &AesKey); 425 dIn = &dIn[16]; 426 dOut = &dOut[16]; 427 } 428 return CRYPT_SUCCESS; 429 } 430 // 431 // 432 // _cpri__AESEncryptOFB() 433 // 434 // This function performs AES encryption/decryption in OFB chain mode. The dIn buffer is modified to 435 // contain the encrypted/decrypted text. 436 // The input iv buffer is assumed to have a size equal to the block size (16 bytes). The returned value of iv 437 // will be the nth encryption of the IV, where n is the number of blocks (full or partial) in the data stream. 438 // 439 // 440 // 441 // 442 // Return Value Meaning 443 // 444 // CRYPT_SUCCESS no non-fatal errors 445 // 446 LIB_EXPORT CRYPT_RESULT 447 _cpri__AESEncryptOFB( 448 BYTE *dOut, // OUT: the encrypted/decrypted data 449 UINT32 keySizeInBits, // IN: key size in bit 450 BYTE *key, // IN: key buffer. The size of this buffer in 451 // bytes is (keySizeInBits + 7) / 8 452 BYTE *iv, // IN/OUT: IV for decryption. The size of this 453 // buffer is 16 byte 454 UINT32 dInSize, // IN: data size 455 BYTE *dIn // IN: data buffer 456 ) 457 { 458 BYTE *pIv; 459 AES_KEY AesKey; 460 INT32 dSize; 461 int i; 462 pAssert(dOut != NULL && key != NULL && iv != NULL && dIn != NULL); 463 if(dInSize == 0) 464 return CRYPT_SUCCESS; 465 pAssert(dInSize <= INT32_MAX); 466 dSize = (INT32)dInSize; 467 // Create AES key schedule 468 if (AES_set_encrypt_key(key, keySizeInBits, &AesKey) != 0) 469 FAIL(FATAL_ERROR_INTERNAL); 470 // This is written so that dIn and dOut may be the same 471 for(; dSize > 0; dSize -= 16) 472 { 473 // Encrypt the current value of the "IV" 474 AES_encrypt(iv, iv, &AesKey); 475 // XOR the encrypted IV into dIn to create the cipher text (dOut) 476 pIv = iv; 477 for(i = (dSize < 16) ? dSize : 16; i > 0; i--) 478 *dOut++ = (*pIv++ ^ *dIn++); 479 } 480 return CRYPT_SUCCESS; 481 } 482 #ifdef TPM_ALG_SM4 483 // 484 // 485 // SM4 Encryption 486 // 487 // _cpri__SM4EncryptCBC() 488 // 489 // This function performs SM4 encryption in CBC chain mode. The input dIn buffer is encrypted into dOut. 490 // The input iv buffer is required to have a size equal to the block size (16 bytes). The dInSize is required to 491 // be a multiple of the block size. 492 // 493 // Return Value Meaning 494 // 495 // CRYPT_SUCCESS if success 496 // CRYPT_PARAMETER dInSize is not a multiple of the block size 497 // 498 LIB_EXPORT CRYPT_RESULT 499 _cpri__SM4EncryptCBC( 500 BYTE *dOut, // OUT: 501 UINT32 keySizeInBits, // IN: key size in bit 502 BYTE *key, // IN: key buffer. The size of this buffer in 503 // bytes is (keySizeInBits + 7) / 8 504 BYTE *iv, // IN/OUT: IV for decryption. 505 UINT32 dInSize, // IN: data size (is required to be a multiple 506 // of 16 bytes) 507 BYTE *dIn // IN: data buffer 508 ) 509 { 510 SM4_KEY Sm4Key; 511 BYTE *pIv; 512 INT32 dSize; // Need a signed version 513 int i; 514 pAssert(dOut != NULL && key != NULL && iv != NULL && dIn != NULL); 515 if(dInSize == 0) 516 return CRYPT_SUCCESS; 517 pAssert(dInSize <= INT32_MAX); 518 dSize = (INT32)dInSize; 519 // For CBC, the data size must be an even multiple of the 520 // cipher block size 521 if((dSize % 16) != 0) 522 return CRYPT_PARAMETER; 523 // Create SM4 encrypt key schedule 524 if (SM4_set_encrypt_key(key, keySizeInBits, &Sm4Key) != 0) 525 FAIL(FATAL_ERROR_INTERNAL); 526 // XOR the data block into the IV, encrypt the IV into the IV 527 // and then copy the IV to the output 528 for(; dSize > 0; dSize -= 16) 529 { 530 pIv = iv; 531 for(i = 16; i > 0; i--) 532 *pIv++ ^= *dIn++; 533 SM4_encrypt(iv, iv, &Sm4Key); 534 pIv = iv; 535 for(i = 16; i > 0; i--) 536 *dOut++ = *pIv++; 537 } 538 return CRYPT_SUCCESS; 539 } 540 // 541 // 542 // _cpri__SM4DecryptCBC() 543 // 544 // This function performs SM4 decryption in CBC chain mode. The input dIn buffer is decrypted into dOut. 545 // The input iv buffer is required to have a size equal to the block size (16 bytes). The dInSize is required to 546 // be a multiple of the block size. 547 // 548 // Return Value Meaning 549 // 550 // CRYPT_SUCCESS if success 551 // CRYPT_PARAMETER dInSize is not a multiple of the block size 552 // 553 LIB_EXPORT CRYPT_RESULT 554 _cpri__SM4DecryptCBC( 555 BYTE *dOut, // OUT: the decrypted data 556 UINT32 keySizeInBits, // IN: key size in bit 557 BYTE *key, // IN: key buffer. The size of this buffer in 558 // bytes is (keySizeInBits + 7) / 8 559 BYTE *iv, // IN/OUT: IV for decryption. The size of this 560 // buffer is 16 byte 561 UINT32 dInSize, // IN: data size 562 BYTE *dIn // IN: data buffer 563 ) 564 { 565 SM4_KEY Sm4Key; 566 BYTE *pIv; 567 int i; 568 BYTE tmp[16]; 569 BYTE *pT = NULL; 570 INT32 dSize; 571 pAssert(dOut != NULL && key != NULL && iv != NULL && dIn != NULL); 572 if(dInSize == 0) 573 return CRYPT_SUCCESS; 574 pAssert(dInSize <= INT32_MAX); 575 dSize = (INT32)dInSize; 576 // For CBC, the data size must be an even multiple of the 577 // cipher block size 578 if((dSize % 16) != 0) 579 return CRYPT_PARAMETER; 580 // Create SM4 key schedule 581 if (SM4_set_decrypt_key(key, keySizeInBits, &Sm4Key) != 0) 582 FAIL(FATAL_ERROR_INTERNAL); 583 // Copy the input data to a temp buffer, decrypt the buffer into the output; 584 // XOR in the IV, and copy the temp buffer to the IV and repeat. 585 for(; dSize > 0; dSize -= 16) 586 { 587 pT = tmp; 588 for(i = 16; i> 0; i--) 589 *pT++ = *dIn++; 590 SM4_decrypt(tmp, dOut, &Sm4Key); 591 pIv = iv; 592 pT = tmp; 593 for(i = 16; i> 0; i--) 594 { 595 *dOut++ ^= *pIv; 596 // 597 *pIv++ = *pT++; 598 } 599 } 600 return CRYPT_SUCCESS; 601 } 602 // 603 // 604 // _cpri__SM4EncryptCFB() 605 // 606 // This function performs SM4 encryption in CFB chain mode. The dOut buffer receives the values 607 // encrypted dIn. The input iv is assumed to be the size of an encryption block (16 bytes). The iv buffer will 608 // be modified to contain the last encrypted block. 609 // 610 // Return Value Meaning 611 // 612 // CRYPT_SUCCESS no non-fatal errors 613 // 614 LIB_EXPORT CRYPT_RESULT 615 _cpri__SM4EncryptCFB( 616 BYTE *dOut, // OUT: the encrypted 617 UINT32 keySizeInBits, // IN: key size in bit 618 BYTE *key, // IN: key buffer. The size of this buffer in 619 // bytes is (keySizeInBits + 7) / 8 620 BYTE *iv, // IN/OUT: IV for decryption. 621 UINT32 dInSize, // IN: data size 622 BYTE *dIn // IN: data buffer 623 ) 624 { 625 BYTE *pIv; 626 SM4_KEY Sm4Key; 627 INT32 dSize; // Need a signed version of dInSize 628 int i; 629 pAssert(dOut != NULL && key != NULL && iv != NULL && dIn != NULL); 630 if(dInSize == 0) 631 return CRYPT_SUCCESS; 632 pAssert(dInSize <= INT32_MAX); 633 dSize = (INT32)dInSize; 634 // Create SM4 encryption key schedule 635 if (SM4_set_encrypt_key(key, keySizeInBits, &Sm4Key) != 0) 636 FAIL(FATAL_ERROR_INTERNAL); 637 // Encrypt the IV into the IV, XOR in the data, and copy to output 638 for(; dSize > 0; dSize -= 16) 639 { 640 // Encrypt the current value of the IV 641 SM4_encrypt(iv, iv, &Sm4Key); 642 pIv = iv; 643 for(i = (int)(dSize < 16) ? dSize : 16; i > 0; i--) 644 // XOR the data into the IV to create the cipher text 645 // and put into the output 646 *dOut++ = *pIv++ ^= *dIn++; 647 } 648 return CRYPT_SUCCESS; 649 } 650 // 651 // 652 // _cpri__SM4DecryptCFB() 653 // 654 // This function performs SM4 decrypt in CFB chain mode. The dOut buffer receives the values decrypted 655 // from dIn. 656 // 657 // The input iv is assumed to be the size of an encryption block (16 bytes). The iv buffer will be modified to 658 // contain the last decoded block, padded with zeros 659 // 660 // Return Value Meaning 661 // 662 // CRYPT_SUCCESS no non-fatal errors 663 // 664 LIB_EXPORT CRYPT_RESULT 665 _cpri__SM4DecryptCFB( 666 BYTE *dOut, // OUT: the decrypted data 667 UINT32 keySizeInBits, // IN: key size in bit 668 BYTE *key, // IN: key buffer. The size of this buffer in 669 // bytes is (keySizeInBits + 7) / 8 670 BYTE *iv, // IN/OUT: IV for decryption. 671 UINT32 dInSize, // IN: data size 672 BYTE *dIn // IN: data buffer 673 ) 674 { 675 BYTE *pIv; 676 BYTE tmp[16]; 677 int i; 678 BYTE *pT; 679 SM4_KEY Sm4Key; 680 INT32 dSize; 681 pAssert(dOut != NULL && key != NULL && iv != NULL && dIn != NULL); 682 if(dInSize == 0) 683 return CRYPT_SUCCESS; 684 pAssert(dInSize <= INT32_MAX); 685 dSize = (INT32)dInSize; 686 // Create SM4 encryption key schedule 687 if (SM4_set_encrypt_key(key, keySizeInBits, &Sm4Key) != 0) 688 FAIL(FATAL_ERROR_INTERNAL); 689 for(; dSize > 0; dSize -= 16) 690 { 691 // Encrypt the IV into the temp buffer 692 SM4_encrypt(iv, tmp, &Sm4Key); 693 pT = tmp; 694 pIv = iv; 695 for(i = (dSize < 16) ? dSize : 16; i > 0; i--) 696 // Copy the current cipher text to IV, XOR 697 // with the temp buffer and put into the output 698 *dOut++ = *pT++ ^ (*pIv++ = *dIn++); 699 } 700 // If the inner loop (i loop) was smaller than 16, then dSize 701 // would have been smaller than 16 and it is now negative 702 // If it is negative, then it indicates how may fill bytes 703 // are needed to pad out the IV for the next round. 704 for(; dSize < 0; dSize++) 705 *iv++ = 0; 706 return CRYPT_SUCCESS; 707 } 708 // 709 // 710 // _cpri__SM4EncryptCTR() 711 // 712 // This function performs SM4 encryption/decryption in CTR chain mode. The dIn buffer is encrypted into 713 // dOut. The input iv buffer is assumed to have a size equal to the SM4 block size (16 bytes). The iv will be 714 // incremented by the number of blocks (full and partial) that were encrypted. 715 // 716 // Return Value Meaning 717 // 718 // CRYPT_SUCCESS no non-fatal errors 719 // 720 LIB_EXPORT CRYPT_RESULT 721 _cpri__SM4EncryptCTR( 722 BYTE *dOut, // OUT: the encrypted data 723 UINT32 keySizeInBits, // IN: key size in bit 724 BYTE *key, // IN: key buffer. The size of this buffer in 725 // bytes is (keySizeInBits + 7) / 8 726 BYTE *iv, // IN/OUT: IV for decryption. 727 UINT32 dInSize, // IN: data size 728 BYTE *dIn // IN: data buffer 729 ) 730 { 731 BYTE tmp[16]; 732 BYTE *pT; 733 SM4_KEY Sm4Key; 734 int i; 735 INT32 dSize; 736 pAssert(dOut != NULL && key != NULL && iv != NULL && dIn != NULL); 737 if(dInSize == 0) 738 return CRYPT_SUCCESS; 739 pAssert(dInSize <= INT32_MAX); 740 dSize = (INT32)dInSize; 741 // Create SM4 encryption schedule 742 if (SM4_set_encrypt_key(key, keySizeInBits, &Sm4Key) != 0) 743 FAIL(FATAL_ERROR_INTERNAL); 744 for(; dSize > 0; dSize--) 745 { 746 // Encrypt the current value of the IV(counter) 747 SM4_encrypt(iv, (BYTE *)tmp, &Sm4Key); 748 //increment the counter 749 for(i = 0; i < 16; i++) 750 if((iv[i] += 1) != 0) 751 break; 752 // XOR the encrypted counter value with input and put into output 753 pT = tmp; 754 for(i = (dSize < 16) ? dSize : 16; i > 0; i--) 755 *dOut++ = *dIn++ ^ *pT++; 756 } 757 return CRYPT_SUCCESS; 758 } 759 // 760 // _cpri__SM4EncryptECB() 761 // 762 // SM4 encryption in ECB mode. The data buffer is modified to contain the cipher text. 763 // 764 // Return Value Meaning 765 // 766 // CRYPT_SUCCESS no non-fatal errors 767 // 768 LIB_EXPORT CRYPT_RESULT 769 _cpri__SM4EncryptECB( 770 BYTE *dOut, // OUT: encrypted data 771 UINT32 keySizeInBits, // IN: key size in bit 772 BYTE *key, // IN: key buffer. The size of this buffer in 773 // bytes is (keySizeInBits + 7) / 8 774 UINT32 dInSize, // IN: data size 775 BYTE *dIn // IN: clear text buffer 776 ) 777 { 778 SM4_KEY Sm4Key; 779 INT32 dSize; 780 pAssert(dOut != NULL && key != NULL && dIn != NULL); 781 if(dInSize == 0) 782 return CRYPT_SUCCESS; 783 pAssert(dInSize <= INT32_MAX); 784 dSize = (INT32)dInSize; 785 // For ECB, the data size must be an even multiple of the 786 // cipher block size 787 if((dSize % 16) != 0) 788 return CRYPT_PARAMETER; 789 // Create SM4 encrypting key schedule 790 if (SM4_set_encrypt_key(key, keySizeInBits, &Sm4Key) != 0) 791 FAIL(FATAL_ERROR_INTERNAL); 792 for(; dSize > 0; dSize -= 16) 793 { 794 SM4_encrypt(dIn, dOut, &Sm4Key); 795 dIn = &dIn[16]; 796 dOut = &dOut[16]; 797 } 798 return CRYPT_SUCCESS; 799 } 800 // 801 // 802 // _cpri__SM4DecryptECB() 803 // 804 // This function performs SM4 decryption using ECB (not recommended). The cipher text dIn is decrypted 805 // into dOut. 806 // 807 // 808 // 809 // 810 // Return Value Meaning 811 // 812 // CRYPT_SUCCESS no non-fatal errors 813 // 814 LIB_EXPORT CRYPT_RESULT 815 _cpri__SM4DecryptECB( 816 BYTE *dOut, // OUT: the clear text data 817 UINT32 keySizeInBits, // IN: key size in bit 818 BYTE *key, // IN: key buffer. The size of this buffer in 819 // bytes is (keySizeInBits + 7) / 8 820 UINT32 dInSize, // IN: data size 821 BYTE *dIn // IN: cipher text buffer 822 ) 823 { 824 SM4_KEY Sm4Key; 825 INT32 dSize; 826 pAssert(dOut != NULL && key != NULL && dIn != NULL); 827 if(dInSize == 0) 828 return CRYPT_SUCCESS; 829 pAssert(dInSize <= INT32_MAX); 830 dSize = (INT32)dInSize; 831 // For ECB, the data size must be an even multiple of the 832 // cipher block size 833 if((dSize % 16) != 0) 834 return CRYPT_PARAMETER; 835 // Create SM4 decryption key schedule 836 if (SM4_set_decrypt_key(key, keySizeInBits, &Sm4Key) != 0) 837 FAIL(FATAL_ERROR_INTERNAL); 838 for(; dSize > 0; dSize -= 16) 839 { 840 SM4_decrypt(dIn, dOut, &Sm4Key); 841 dIn = &dIn[16]; 842 dOut = &dOut[16]; 843 } 844 return CRYPT_SUCCESS; 845 } 846 // 847 // 848 // _cpri__SM4EncryptOFB() 849 // 850 // This function performs SM4 encryption/decryption in OFB chain mode. The dIn buffer is modified to 851 // contain the encrypted/decrypted text. 852 // The input iv buffer is assumed to have a size equal to the block size (16 bytes). The returned value of iv 853 // will be the nth encryption of the IV, where n is the number of blocks (full or partial) in the data stream. 854 // 855 // Return Value Meaning 856 // 857 // CRYPT_SUCCESS no non-fatal errors 858 // 859 LIB_EXPORT CRYPT_RESULT 860 _cpri__SM4EncryptOFB( 861 BYTE *dOut, // OUT: the encrypted/decrypted data 862 UINT32 keySizeInBits, // IN: key size in bit 863 BYTE *key, // IN: key buffer. The size of this buffer in 864 // bytes is (keySizeInBits + 7) / 8 865 BYTE *iv, // IN/OUT: IV for decryption. The size of this 866 // buffer is 16 byte 867 UINT32 dInSize, // IN: data size 868 BYTE *dIn // IN: data buffer 869 ) 870 { 871 BYTE *pIv; 872 SM4_KEY Sm4Key; 873 INT32 dSize; 874 int i; 875 pAssert(dOut != NULL && key != NULL && iv != NULL && dIn != NULL); 876 if(dInSize == 0) 877 return CRYPT_SUCCESS; 878 pAssert(dInSize <= INT32_MAX); 879 dSize = (INT32)dInSize; 880 // Create SM4 key schedule 881 if (SM4_set_encrypt_key(key, keySizeInBits, &Sm4Key) != 0) 882 FAIL(FATAL_ERROR_INTERNAL); 883 // This is written so that dIn and dOut may be the same 884 for(; dSize > 0; dSize -= 16) 885 { 886 // Encrypt the current value of the "IV" 887 SM4_encrypt(iv, iv, &Sm4Key); 888 // XOR the encrypted IV into dIn to create the cipher text (dOut) 889 pIv = iv; 890 for(i = (dSize < 16) ? dSize : 16; i > 0; i--) 891 *dOut++ = (*pIv++ ^ *dIn++); 892 } 893 return CRYPT_SUCCESS; 894 } 895 #endif //% TPM_ALG_SM4 896