aeskeywrap.c (20135B)
1 /* 2 * aeskeywrap.c - implement AES Key Wrap algorithm from RFC 3394 3 * 4 * This Source Code Form is subject to the terms of the Mozilla Public 5 * License, v. 2.0. If a copy of the MPL was not distributed with this 6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 7 8 #ifdef FREEBL_NO_DEPEND 9 #include "stubs.h" 10 #endif 11 12 #include <stddef.h> 13 14 #include "prcpucfg.h" 15 #if defined(IS_LITTLE_ENDIAN) || defined(SHA_NO_LONG_LONG) 16 #define BIG_ENDIAN_WITH_64_BIT_REGISTERS 0 17 #else 18 #define BIG_ENDIAN_WITH_64_BIT_REGISTERS 1 19 #endif 20 #include "prtypes.h" /* for PRUintXX */ 21 #include "secport.h" /* for PORT_XXX */ 22 #include "secerr.h" 23 #include "blapi.h" /* for AES_ functions */ 24 #include "rijndael.h" 25 26 struct AESKeyWrapContextStr { 27 AESContext aescx; 28 unsigned char iv[AES_KEY_WRAP_IV_BYTES]; 29 void *mem; /* Pointer to beginning of allocated memory. */ 30 }; 31 32 /******************************************/ 33 /* 34 ** AES key wrap algorithm, RFC 3394 35 */ 36 37 AESKeyWrapContext * 38 AESKeyWrap_AllocateContext(void) 39 { 40 /* aligned_alloc is C11 so we have to do it the old way. */ 41 AESKeyWrapContext *ctx = PORT_ZAlloc(sizeof(AESKeyWrapContext) + 15); 42 if (ctx == NULL) { 43 PORT_SetError(SEC_ERROR_NO_MEMORY); 44 return NULL; 45 } 46 ctx->mem = ctx; 47 return (AESKeyWrapContext *)(((uintptr_t)ctx + 15) & ~(uintptr_t)0x0F); 48 } 49 50 SECStatus 51 AESKeyWrap_InitContext(AESKeyWrapContext *cx, 52 const unsigned char *key, 53 unsigned int keylen, 54 const unsigned char *iv, 55 int x1, 56 unsigned int encrypt, 57 unsigned int x2) 58 { 59 SECStatus rv = SECFailure; 60 if (!cx) { 61 PORT_SetError(SEC_ERROR_INVALID_ARGS); 62 return SECFailure; 63 } 64 if (iv) { 65 memcpy(cx->iv, iv, sizeof cx->iv); 66 } else { 67 memset(cx->iv, 0xA6, sizeof cx->iv); 68 } 69 rv = AES_InitContext(&cx->aescx, key, keylen, NULL, NSS_AES, encrypt, 70 AES_BLOCK_SIZE); 71 return rv; 72 } 73 74 /* 75 ** Create a new AES context suitable for AES encryption/decryption. 76 ** "key" raw key data 77 ** "keylen" the number of bytes of key data (16, 24, or 32) 78 */ 79 extern AESKeyWrapContext * 80 AESKeyWrap_CreateContext(const unsigned char *key, const unsigned char *iv, 81 int encrypt, unsigned int keylen) 82 { 83 SECStatus rv; 84 AESKeyWrapContext *cx = AESKeyWrap_AllocateContext(); 85 if (!cx) 86 return NULL; /* error is already set */ 87 rv = AESKeyWrap_InitContext(cx, key, keylen, iv, 0, encrypt, 0); 88 if (rv != SECSuccess) { 89 PORT_Free(cx->mem); 90 cx = NULL; /* error should already be set */ 91 } 92 return cx; 93 } 94 95 /* 96 ** Destroy a AES KeyWrap context. 97 ** "cx" the context 98 ** "freeit" if PR_TRUE then free the object as well as its sub-objects 99 */ 100 extern void 101 AESKeyWrap_DestroyContext(AESKeyWrapContext *cx, PRBool freeit) 102 { 103 if (cx) { 104 AES_DestroyContext(&cx->aescx, PR_FALSE); 105 /* memset(cx, 0, sizeof *cx); */ 106 if (freeit) { 107 PORT_Free(cx->mem); 108 } 109 } 110 } 111 112 #if !BIG_ENDIAN_WITH_64_BIT_REGISTERS 113 114 /* The AES Key Wrap algorithm has 64-bit values that are ALWAYS big-endian 115 ** (Most significant byte first) in memory. The only ALU operations done 116 ** on them are increment, decrement, and XOR. So, on little-endian CPUs, 117 ** and on CPUs that lack 64-bit registers, these big-endian 64-bit operations 118 ** are simulated in the following code. This is thought to be faster and 119 ** simpler than trying to convert the data to little-endian and back. 120 */ 121 122 /* A and T point to two 64-bit values stored most signficant byte first 123 ** (big endian). This function increments the 64-bit value T, and then 124 ** XORs it with A, changing A. 125 */ 126 static void 127 increment_and_xor(unsigned char *A, unsigned char *T) 128 { 129 if (!++T[7]) 130 if (!++T[6]) 131 if (!++T[5]) 132 if (!++T[4]) 133 if (!++T[3]) 134 if (!++T[2]) 135 if (!++T[1]) 136 ++T[0]; 137 138 A[0] ^= T[0]; 139 A[1] ^= T[1]; 140 A[2] ^= T[2]; 141 A[3] ^= T[3]; 142 A[4] ^= T[4]; 143 A[5] ^= T[5]; 144 A[6] ^= T[6]; 145 A[7] ^= T[7]; 146 } 147 148 /* A and T point to two 64-bit values stored most signficant byte first 149 ** (big endian). This function XORs T with A, giving a new A, then 150 ** decrements the 64-bit value T. 151 */ 152 static void 153 xor_and_decrement(PRUint64 *A, PRUint64 *T) 154 { 155 unsigned char *TP = (unsigned char *)T; 156 const PRUint64 mask = 0xFF; 157 *A = ((*A & mask << 56) ^ (*T & mask << 56)) | 158 ((*A & mask << 48) ^ (*T & mask << 48)) | 159 ((*A & mask << 40) ^ (*T & mask << 40)) | 160 ((*A & mask << 32) ^ (*T & mask << 32)) | 161 ((*A & mask << 24) ^ (*T & mask << 23)) | 162 ((*A & mask << 16) ^ (*T & mask << 16)) | 163 ((*A & mask << 8) ^ (*T & mask << 8)) | 164 ((*A & mask) ^ (*T & mask)); 165 166 if (!TP[7]--) 167 if (!TP[6]--) 168 if (!TP[5]--) 169 if (!TP[4]--) 170 if (!TP[3]--) 171 if (!TP[2]--) 172 if (!TP[1]--) 173 TP[0]--; 174 } 175 176 /* Given an unsigned long t (in host byte order), store this value as a 177 ** 64-bit big-endian value (MSB first) in *pt. 178 */ 179 static void 180 set_t(unsigned char *pt, unsigned long t) 181 { 182 pt[7] = (unsigned char)t; 183 t >>= 8; 184 pt[6] = (unsigned char)t; 185 t >>= 8; 186 pt[5] = (unsigned char)t; 187 t >>= 8; 188 pt[4] = (unsigned char)t; 189 t >>= 8; 190 pt[3] = (unsigned char)t; 191 t >>= 8; 192 pt[2] = (unsigned char)t; 193 t >>= 8; 194 pt[1] = (unsigned char)t; 195 t >>= 8; 196 pt[0] = (unsigned char)t; 197 } 198 199 #endif 200 201 static void 202 encode_PRUint32_BE(unsigned char *data, PRUint32 val) 203 { 204 size_t i; 205 for (i = 0; i < sizeof(PRUint32); i++) { 206 data[i] = PORT_GET_BYTE_BE(val, i, sizeof(PRUint32)); 207 } 208 } 209 210 static PRUint32 211 decode_PRUint32_BE(unsigned char *data) 212 { 213 PRUint32 val = 0; 214 size_t i; 215 216 for (i = 0; i < sizeof(PRUint32); i++) { 217 val = (val << PR_BITS_PER_BYTE) | data[i]; 218 } 219 return val; 220 } 221 222 /* 223 ** Perform AES key wrap W function. 224 ** "cx" the context 225 ** "iv" the iv is concatenated to the plain text for for executing the function 226 ** "output" the output buffer to store the encrypted data. 227 ** "pOutputLen" how much data is stored in "output". Set by the routine 228 ** after some data is stored in output. 229 ** "maxOutputLen" the maximum amount of data that can ever be 230 ** stored in "output" 231 ** "input" the input data 232 ** "inputLen" the amount of input data 233 */ 234 extern SECStatus 235 AESKeyWrap_W(AESKeyWrapContext *cx, unsigned char *iv, unsigned char *output, 236 unsigned int *pOutputLen, unsigned int maxOutputLen, 237 const unsigned char *input, unsigned int inputLen) 238 { 239 PRUint64 *R = NULL; 240 unsigned int nBlocks; 241 unsigned int i, j; 242 unsigned int aesLen = AES_BLOCK_SIZE; 243 unsigned int outLen = inputLen + AES_KEY_WRAP_BLOCK_SIZE; 244 SECStatus s = SECFailure; 245 /* These PRUint64s are ALWAYS big endian, regardless of CPU orientation. */ 246 PRUint64 t; 247 PRUint64 B[2]; 248 249 #define A B[0] 250 251 /* Check args */ 252 if (inputLen < 2 * AES_KEY_WRAP_BLOCK_SIZE || 253 0 != inputLen % AES_KEY_WRAP_BLOCK_SIZE) { 254 PORT_SetError(SEC_ERROR_INPUT_LEN); 255 return s; 256 } 257 #ifdef maybe 258 if (!output && pOutputLen) { /* caller is asking for output size */ 259 *pOutputLen = outLen; 260 return SECSuccess; 261 } 262 #endif 263 if (maxOutputLen < outLen) { 264 PORT_SetError(SEC_ERROR_OUTPUT_LEN); 265 return s; 266 } 267 if (cx == NULL || output == NULL || input == NULL) { 268 PORT_SetError(SEC_ERROR_INVALID_ARGS); 269 return s; 270 } 271 nBlocks = inputLen / AES_KEY_WRAP_BLOCK_SIZE; 272 R = PORT_NewArray(PRUint64, nBlocks + 1); 273 if (!R) 274 return s; /* error is already set. */ 275 /* 276 ** 1) Initialize variables. 277 */ 278 memcpy(&A, iv, AES_KEY_WRAP_IV_BYTES); 279 memcpy(&R[1], input, inputLen); 280 #if BIG_ENDIAN_WITH_64_BIT_REGISTERS 281 t = 0; 282 #else 283 memset(&t, 0, sizeof t); 284 #endif 285 /* 286 ** 2) Calculate intermediate values. 287 */ 288 for (j = 0; j < 6; ++j) { 289 for (i = 1; i <= nBlocks; ++i) { 290 B[1] = R[i]; 291 s = AES_Encrypt(&cx->aescx, (unsigned char *)B, &aesLen, 292 sizeof B, (unsigned char *)B, sizeof B); 293 if (s != SECSuccess) 294 break; 295 R[i] = B[1]; 296 /* here, increment t and XOR A with t (in big endian order); */ 297 #if BIG_ENDIAN_WITH_64_BIT_REGISTERS 298 A ^= ++t; 299 #else 300 increment_and_xor((unsigned char *)&A, (unsigned char *)&t); 301 #endif 302 } 303 } 304 /* 305 ** 3) Output the results. 306 */ 307 if (s == SECSuccess) { 308 R[0] = A; 309 memcpy(output, &R[0], outLen); 310 if (pOutputLen) 311 *pOutputLen = outLen; 312 } else if (pOutputLen) { 313 *pOutputLen = 0; 314 } 315 PORT_ZFree(R, outLen); 316 return s; 317 } 318 #undef A 319 320 /* 321 ** Perform AES key wrap W^-1 function. 322 ** "cx" the context 323 ** "iv" the input IV to verify against. If NULL, then skip verification. 324 ** "ivOut" the output buffer to store the IV (optional). 325 ** "output" the output buffer to store the decrypted data. 326 ** "pOutputLen" how much data is stored in "output". Set by the routine 327 ** after some data is stored in output. 328 ** "maxOutputLen" the maximum amount of data that can ever be 329 ** stored in "output" 330 ** "input" the input data 331 ** "inputLen" the amount of input data 332 */ 333 extern SECStatus 334 AESKeyWrap_Winv(AESKeyWrapContext *cx, unsigned char *iv, 335 unsigned char *ivOut, unsigned char *output, 336 unsigned int *pOutputLen, unsigned int maxOutputLen, 337 const unsigned char *input, unsigned int inputLen) 338 { 339 PRUint64 *R = NULL; 340 unsigned int nBlocks; 341 unsigned int i, j; 342 unsigned int aesLen = AES_BLOCK_SIZE; 343 unsigned int outLen; 344 SECStatus s = SECFailure; 345 /* These PRUint64s are ALWAYS big endian, regardless of CPU orientation. */ 346 PRUint64 t; 347 PRUint64 B[2]; 348 349 /* Check args */ 350 if (inputLen < 3 * AES_KEY_WRAP_BLOCK_SIZE || 351 0 != inputLen % AES_KEY_WRAP_BLOCK_SIZE) { 352 PORT_SetError(SEC_ERROR_INPUT_LEN); 353 return s; 354 } 355 outLen = inputLen - AES_KEY_WRAP_BLOCK_SIZE; 356 #ifdef maybe 357 if (!output && pOutputLen) { /* caller is asking for output size */ 358 *pOutputLen = outLen; 359 return SECSuccess; 360 } 361 #endif 362 if (maxOutputLen < outLen) { 363 PORT_SetError(SEC_ERROR_OUTPUT_LEN); 364 return s; 365 } 366 if (cx == NULL || output == NULL || input == NULL) { 367 PORT_SetError(SEC_ERROR_INVALID_ARGS); 368 return s; 369 } 370 nBlocks = inputLen / AES_KEY_WRAP_BLOCK_SIZE; 371 R = PORT_NewArray(PRUint64, nBlocks); 372 if (!R) 373 return s; /* error is already set. */ 374 nBlocks--; 375 /* 376 ** 1) Initialize variables. 377 */ 378 memcpy(&R[0], input, inputLen); 379 B[0] = R[0]; 380 #if BIG_ENDIAN_WITH_64_BIT_REGISTERS 381 t = 6UL * nBlocks; 382 #else 383 set_t((unsigned char *)&t, 6UL * nBlocks); 384 #endif 385 /* 386 ** 2) Calculate intermediate values. 387 */ 388 for (j = 0; j < 6; ++j) { 389 for (i = nBlocks; i; --i) { 390 /* here, XOR A with t (in big endian order) and decrement t; */ 391 #if BIG_ENDIAN_WITH_64_BIT_REGISTERS 392 B[0] ^= t--; 393 #else 394 xor_and_decrement(&B[0], &t); 395 #endif 396 B[1] = R[i]; 397 s = AES_Decrypt(&cx->aescx, (unsigned char *)B, &aesLen, 398 sizeof B, (unsigned char *)B, sizeof B); 399 if (s != SECSuccess) 400 break; 401 R[i] = B[1]; 402 } 403 } 404 /* 405 ** 3) Output the results. 406 */ 407 if (s == SECSuccess) { 408 int bad = (iv) && memcmp(&B[0], iv, AES_KEY_WRAP_IV_BYTES); 409 if (!bad) { 410 memcpy(output, &R[1], outLen); 411 if (pOutputLen) 412 *pOutputLen = outLen; 413 if (ivOut) { 414 memcpy(ivOut, &B[0], AES_KEY_WRAP_IV_BYTES); 415 } 416 } else { 417 s = SECFailure; 418 PORT_SetError(SEC_ERROR_BAD_DATA); 419 if (pOutputLen) 420 *pOutputLen = 0; 421 } 422 } else if (pOutputLen) { 423 *pOutputLen = 0; 424 } 425 PORT_ZFree(R, inputLen); 426 return s; 427 } 428 #undef A 429 430 /* 431 ** Perform AES key wrap. 432 ** "cx" the context 433 ** "output" the output buffer to store the encrypted data. 434 ** "pOutputLen" how much data is stored in "output". Set by the routine 435 ** after some data is stored in output. 436 ** "maxOutputLen" the maximum amount of data that can ever be 437 ** stored in "output" 438 ** "input" the input data 439 ** "inputLen" the amount of input data 440 */ 441 extern SECStatus 442 AESKeyWrap_Encrypt(AESKeyWrapContext *cx, unsigned char *output, 443 unsigned int *pOutputLen, unsigned int maxOutputLen, 444 const unsigned char *input, unsigned int inputLen) 445 { 446 return AESKeyWrap_W(cx, cx->iv, output, pOutputLen, maxOutputLen, 447 input, inputLen); 448 } 449 450 /* 451 ** Perform AES key unwrap. 452 ** "cx" the context 453 ** "output" the output buffer to store the decrypted data. 454 ** "pOutputLen" how much data is stored in "output". Set by the routine 455 ** after some data is stored in output. 456 ** "maxOutputLen" the maximum amount of data that can ever be 457 ** stored in "output" 458 ** "input" the input data 459 ** "inputLen" the amount of input data 460 */ 461 extern SECStatus 462 AESKeyWrap_Decrypt(AESKeyWrapContext *cx, unsigned char *output, 463 unsigned int *pOutputLen, unsigned int maxOutputLen, 464 const unsigned char *input, unsigned int inputLen) 465 { 466 return AESKeyWrap_Winv(cx, cx->iv, NULL, output, pOutputLen, maxOutputLen, 467 input, inputLen); 468 } 469 470 #define BLOCK_PAD_POWER2(x, bs) (((bs) - ((x) & ((bs)-1))) & ((bs)-1)) 471 #define AES_KEY_WRAP_ICV2 0xa6, 0x59, 0x59, 0xa6 472 #define AES_KEY_WRAP_ICV2_INT32 0xa65959a6 473 #define AES_KEY_WRAP_ICV2_LEN 4 474 475 /* 476 ** Perform AES key wrap with padding. 477 ** "cx" the context 478 ** "output" the output buffer to store the encrypted data. 479 ** "pOutputLen" how much data is stored in "output". Set by the routine 480 ** after some data is stored in output. 481 ** "maxOutputLen" the maximum amount of data that can ever be 482 ** stored in "output" 483 ** "input" the input data 484 ** "inputLen" the amount of input data 485 */ 486 extern SECStatus 487 AESKeyWrap_EncryptKWP(AESKeyWrapContext *cx, unsigned char *output, 488 unsigned int *pOutputLen, unsigned int maxOutputLen, 489 const unsigned char *input, unsigned int inputLen) 490 { 491 unsigned int padLen = BLOCK_PAD_POWER2(inputLen, AES_KEY_WRAP_BLOCK_SIZE); 492 unsigned int paddedInputLen = inputLen + padLen; 493 unsigned int outLen = paddedInputLen + AES_KEY_WRAP_BLOCK_SIZE; 494 unsigned char iv[AES_BLOCK_SIZE] = { AES_KEY_WRAP_ICV2 }; 495 unsigned char *newBuf; 496 SECStatus rv; 497 498 *pOutputLen = outLen; 499 if (maxOutputLen < outLen) { 500 PORT_SetError(SEC_ERROR_OUTPUT_LEN); 501 return SECFailure; 502 } 503 PORT_Assert((AES_KEY_WRAP_ICV2_LEN + sizeof(PRUint32)) == AES_KEY_WRAP_BLOCK_SIZE); 504 encode_PRUint32_BE(iv + AES_KEY_WRAP_ICV2_LEN, inputLen); 505 506 /* If we can fit in an AES Block, just do and AES Encrypt, 507 * iv is big enough to handle this on the stack, so no need to allocate 508 */ 509 if (outLen == AES_BLOCK_SIZE) { 510 PORT_Assert(inputLen <= AES_KEY_WRAP_BLOCK_SIZE); 511 PORT_Memset(iv + AES_KEY_WRAP_BLOCK_SIZE, 0, AES_KEY_WRAP_BLOCK_SIZE); 512 PORT_Memcpy(iv + AES_KEY_WRAP_BLOCK_SIZE, input, inputLen); 513 rv = AES_Encrypt(&cx->aescx, output, pOutputLen, maxOutputLen, iv, 514 outLen); 515 PORT_SafeZero(iv, sizeof(iv)); 516 return rv; 517 } 518 519 /* add padding to our input block */ 520 newBuf = PORT_ZAlloc(paddedInputLen); 521 if (newBuf == NULL) { 522 return SECFailure; 523 } 524 PORT_Memcpy(newBuf, input, inputLen); 525 526 rv = AESKeyWrap_W(cx, iv, output, pOutputLen, maxOutputLen, 527 newBuf, paddedInputLen); 528 PORT_ZFree(newBuf, paddedInputLen); 529 /* a little overkill, we only need to clear out the length, but this 530 * is easier to verify we got it all */ 531 PORT_SafeZero(iv, sizeof(iv)); 532 return rv; 533 } 534 535 /* 536 ** Perform AES key unwrap with padding. 537 ** "cx" the context 538 ** "output" the output buffer to store the decrypted data. 539 ** "pOutputLen" how much data is stored in "output". Set by the routine 540 ** after some data is stored in output. 541 ** "maxOutputLen" the maximum amount of data that can ever be 542 ** stored in "output" 543 ** "input" the input data 544 ** "inputLen" the amount of input data 545 */ 546 extern SECStatus 547 AESKeyWrap_DecryptKWP(AESKeyWrapContext *cx, unsigned char *output, 548 unsigned int *pOutputLen, unsigned int maxOutputLen, 549 const unsigned char *input, unsigned int inputLen) 550 { 551 unsigned int padLen; 552 unsigned int padLen2; 553 unsigned int outLen; 554 unsigned int paddedLen; 555 unsigned int good; 556 unsigned char *newBuf = NULL; 557 unsigned char *allocBuf = NULL; 558 int i; 559 unsigned char iv[AES_BLOCK_SIZE]; 560 PRUint32 magic; 561 SECStatus rv = SECFailure; 562 563 paddedLen = inputLen - AES_KEY_WRAP_BLOCK_SIZE; 564 /* unwrap the padded result */ 565 if (inputLen == AES_BLOCK_SIZE) { 566 rv = AES_Decrypt(&cx->aescx, iv, &outLen, inputLen, input, inputLen); 567 newBuf = &iv[AES_KEY_WRAP_BLOCK_SIZE]; 568 outLen -= AES_KEY_WRAP_BLOCK_SIZE; 569 } else { 570 /* if the caller supplied enough space to hold the unpadded buffer, 571 * we can unwrap directly into that unpadded buffer. Otherwise 572 * we allocate a buffer that can hold the padding, and we'll copy 573 * the result in a later step */ 574 newBuf = output; 575 if (maxOutputLen < paddedLen) { 576 allocBuf = newBuf = PORT_Alloc(paddedLen); 577 if (!allocBuf) { 578 return SECFailure; 579 } 580 } 581 /* We pass NULL for the first IV argument because we don't know 582 * what the IV has since in includes the length, so we don't have 583 * Winv verify it. We pass iv in the second argument to get the 584 * iv, which we verify below before we return anything */ 585 rv = AESKeyWrap_Winv(cx, NULL, iv, newBuf, &outLen, 586 paddedLen, input, inputLen); 587 } 588 if (rv != SECSuccess) { 589 goto loser; 590 } 591 rv = SECFailure; 592 if (outLen != paddedLen) { 593 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); 594 goto loser; 595 } 596 597 /* we verify the result in a constant time manner */ 598 /* verify ICV magic */ 599 magic = decode_PRUint32_BE(iv); 600 good = PORT_CT_EQ(magic, AES_KEY_WRAP_ICV2_INT32); 601 /* fetch and verify plain text length */ 602 outLen = decode_PRUint32_BE(iv + AES_KEY_WRAP_ICV2_LEN); 603 good &= PORT_CT_LE(outLen, paddedLen); 604 /* now verify the padding */ 605 padLen = paddedLen - outLen; 606 padLen2 = BLOCK_PAD_POWER2(outLen, AES_KEY_WRAP_BLOCK_SIZE); 607 good &= PORT_CT_EQ(padLen, padLen2); 608 for (i = 0; i < AES_KEY_WRAP_BLOCK_SIZE; i++) { 609 unsigned int doTest = PORT_CT_GT(padLen, i); 610 unsigned int result = PORT_CT_ZERO(newBuf[paddedLen - i - 1]); 611 good &= PORT_CT_SEL(doTest, result, PORT_CT_TRUE); 612 } 613 614 /* now if anything was wrong, fail. At this point we will leak timing 615 * information, but we also 'leak' the error code as well. */ 616 if (!good) { 617 PORT_SetError(SEC_ERROR_BAD_DATA); 618 goto loser; 619 } 620 621 /* now copy out the result */ 622 *pOutputLen = outLen; 623 if (maxOutputLen < outLen) { 624 PORT_SetError(SEC_ERROR_OUTPUT_LEN); 625 goto loser; 626 } 627 if (output != newBuf) { 628 PORT_Memcpy(output, newBuf, outLen); 629 } 630 rv = SECSuccess; 631 loser: 632 /* if we failed, make sure we don't return any data to the user */ 633 if ((rv != SECSuccess) && (output == newBuf)) { 634 PORT_SafeZero(newBuf, paddedLen); 635 } 636 /* clear out CSP sensitive data from the heap and stack */ 637 if (allocBuf) { 638 PORT_ZFree(allocBuf, paddedLen); 639 } 640 PORT_SafeZero(iv, sizeof(iv)); 641 return rv; 642 }