blapi_bsf.c
来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 2,087 行 · 第 1/5 页
C
2,087 行
unsigned int *outputLen, unsigned int maxOutputLen, const unsigned char *input, unsigned int inputLen){ int status; unsigned int outputLenUpdate, outputLenFinal; PORT_Assert(cx != NULL); if (cx == NULL) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } PORT_Assert(maxOutputLen >= inputLen); /* check for enough room */ if (maxOutputLen < inputLen) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } if ((status = B_DecryptInit(cx->algobj, cx->keyobj, cx->alg_chooser, (A_SURRENDER_CTX *)NULL_PTR)) != 0) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } if ((status = B_DecryptUpdate(cx->algobj, output, &outputLenUpdate, maxOutputLen, input, inputLen, (B_ALGORITHM_OBJ)NULL_PTR, (A_SURRENDER_CTX *)NULL_PTR)) != 0) { PORT_SetError(SEC_ERROR_BAD_DATA); return SECFailure; } if ((status = B_DecryptFinal(cx->algobj, output + outputLenUpdate, &outputLenFinal, maxOutputLen - outputLenUpdate, (B_ALGORITHM_OBJ)NULL_PTR, (A_SURRENDER_CTX *)NULL_PTR)) != 0) { PORT_SetError(SEC_ERROR_BAD_DATA); return SECFailure; } *outputLen = outputLenUpdate + outputLenFinal; return SECSuccess;}/******************************************************************************* BLAPI implementation of RC5******************************************************************************/struct RC5ContextStr{ B_ALGORITHM_OBJ algobj; B_ALGORITHM_METHOD *alg_chooser[6]; B_KEY_OBJ keyobj; unsigned int blocksize;};RC5Context *RC5_CreateContext(SECItem *key, unsigned int rounds, unsigned int wordSize, unsigned char *iv, int mode){ /* BLAPI */ RC5Context *cx; /* BSAFE */ B_BLK_CIPHER_W_FEEDBACK_PARAMS fbParams; A_RC5_PARAMS rc5Params; ITEM keyItem; ITEM ivItem; unsigned int blocksize; int status; if (rounds > MAX_RC5_ROUNDS) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return NULL; } if (key->len > MAX_RC5_KEY_BYTES) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return NULL; } if (mode == NSS_RC5_CBC && (iv == NULL)) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return NULL; } cx = (RC5Context *)PORT_ZAlloc(sizeof(RC5Context)); if (cx == NULL) { PORT_SetError(PR_OUT_OF_MEMORY_ERROR); return NULL; } cx->algobj = (B_ALGORITHM_OBJ)NULL_PTR; if ((status = B_CreateAlgorithmObject(&cx->algobj)) != 0) { PORT_SetError(PR_OUT_OF_MEMORY_ERROR); goto loser; } cx->keyobj = (B_KEY_OBJ)NULL_PTR; if ((status = B_CreateKeyObject(&cx->keyobj)) != 0) { PORT_SetError(PR_OUT_OF_MEMORY_ERROR); goto loser; } rc5Params.version = RC5_VERSION_NUMBER; rc5Params.rounds = rounds; rc5Params.wordSizeInBits = wordSize * BITS_PER_BYTE; if (rc5Params.wordSizeInBits == 64) { fbParams.encryptionMethodName = (unsigned char *)"rc5_64"; cx->alg_chooser[0] = &AM_RC5_64ENCRYPT; cx->alg_chooser[1] = &AM_RC5_64DECRYPT; } else { fbParams.encryptionMethodName = (unsigned char *)"rc5"; cx->alg_chooser[0] = &AM_RC5_ENCRYPT; cx->alg_chooser[1] = &AM_RC5_DECRYPT; } fbParams.encryptionParams = (POINTER)&rc5Params; fbParams.paddingMethodName = (unsigned char *)"nopad"; fbParams.paddingParams = NULL_PTR; cx->alg_chooser[4] = &AM_SHA_RANDOM; cx->alg_chooser[5] = (B_ALGORITHM_METHOD *)NULL; switch (mode) { case NSS_RC5: blocksize = 2 * wordSize; cx->blocksize = blocksize; fbParams.feedbackMethodName = (unsigned char *)"ecb"; fbParams.feedbackParams = (POINTER)&blocksize; cx->alg_chooser[2] = &AM_ECB_ENCRYPT; cx->alg_chooser[3] = &AM_ECB_DECRYPT; break; case NSS_RC5_CBC: ivItem.len = 2 * wordSize; ivItem.data = iv; cx->blocksize = RC5_BLOCK_SIZE; fbParams.feedbackMethodName = (unsigned char *)"cbc"; fbParams.feedbackParams = (POINTER)&ivItem; cx->alg_chooser[2] = &AM_CBC_ENCRYPT; cx->alg_chooser[3] = &AM_CBC_DECRYPT; break; default: PORT_SetError(SEC_ERROR_INVALID_ARGS); goto loser; } if ((status = B_SetAlgorithmInfo(cx->algobj, AI_FeedbackCipher, (POINTER)&fbParams)) != 0) { PORT_SetError(SEC_ERROR_INVALID_ARGS); goto loser; } keyItem.len = key->len; keyItem.data = key->data; if ((status = B_SetKeyInfo(cx->keyobj, KI_Item, (POINTER)&keyItem)) != 0) { PORT_SetError(SEC_ERROR_INVALID_ARGS); goto loser; } return cx;loser: RC5_DestroyContext(cx, PR_TRUE); return NULL;}void RC5_DestroyContext(RC5Context *cx, PRBool freeit){ if (freeit) { PORT_Assert(cx != NULL); if (cx == NULL) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return; } if (cx->keyobj != NULL_PTR) B_DestroyKeyObject(&cx->keyobj); if (cx->algobj != NULL_PTR) B_DestroyAlgorithmObject(&cx->algobj); PORT_ZFree(cx, sizeof(RC5Context)); }}SECStatus RC5_Encrypt(RC5Context *cx, unsigned char *output, unsigned int *outputLen, unsigned int maxOutputLen, unsigned char *input, unsigned int inputLen){ int status; unsigned int outputLenUpdate, outputLenFinal; PORT_Assert(cx != NULL); if (cx == NULL) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } PORT_Assert((inputLen & (RC5_BLOCK_SIZE - 1)) == 0); if (inputLen & (RC5_BLOCK_SIZE - 1)) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } PORT_Assert(maxOutputLen >= inputLen); /* check for enough room */ if (maxOutputLen < inputLen) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } if ((status = B_EncryptInit(cx->algobj, cx->keyobj, cx->alg_chooser, (A_SURRENDER_CTX *)NULL_PTR)) != 0) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } if ((status = B_EncryptUpdate(cx->algobj, output, &outputLenUpdate, maxOutputLen, input, inputLen, (B_ALGORITHM_OBJ)NULL_PTR, (A_SURRENDER_CTX *)NULL_PTR)) != 0) { PORT_SetError(SEC_ERROR_BAD_DATA); return SECFailure; } if ((status = B_EncryptFinal(cx->algobj, output + outputLenUpdate, &outputLenFinal, maxOutputLen - outputLenUpdate, (B_ALGORITHM_OBJ)NULL_PTR, (A_SURRENDER_CTX *)NULL_PTR)) != 0) { PORT_SetError(SEC_ERROR_BAD_DATA); return SECFailure; } *outputLen = outputLenUpdate + outputLenFinal; return SECSuccess;}SECStatus RC5_Decrypt(RC5Context *cx, unsigned char *output, unsigned int *outputLen, unsigned int maxOutputLen, unsigned char *input, unsigned int inputLen){ int status; unsigned int outputLenUpdate, outputLenFinal; ptrdiff_t inpptr; unsigned char *inp = NULL; PRBool cpybuffer = PR_FALSE; /* The BSAFE Crypto-C 4.1 library with which we tested on a Sun * UltraSparc crashed when the input to an RC5 CBC decryption operation * was not 4-byte aligned. * So, we work around this problem by aligning unaligned input in a * temporary buffer. */ inpptr = (ptrdiff_t)input; if (inpptr & 0x03) { inp = PORT_ZAlloc(inputLen); if (inp == NULL) { PORT_SetError(PR_OUT_OF_MEMORY_ERROR); return SECFailure; } PORT_Memcpy(inp, input, inputLen); cpybuffer = PR_TRUE; } else { inp = input; } PORT_Assert(cx != NULL); if (cx == NULL) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } PORT_Assert((inputLen & (cx->blocksize - 1)) == 0); if (inputLen & (cx->blocksize - 1)) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } PORT_Assert(maxOutputLen >= inputLen); /* check for enough room */ if (maxOutputLen < inputLen) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } if ((status = B_DecryptInit(cx->algobj, cx->keyobj, cx->alg_chooser, (A_SURRENDER_CTX *)NULL_PTR)) != 0) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } if ((status = B_DecryptUpdate(cx->algobj, output, &outputLenUpdate, maxOutputLen, input, inputLen, (B_ALGORITHM_OBJ)NULL_PTR, (A_SURRENDER_CTX *)NULL_PTR)) != 0) { PORT_SetError(SEC_ERROR_BAD_DATA); return SECFailure; } if ((status = B_DecryptFinal(cx->algobj, output + outputLenUpdate, &outputLenFinal, maxOutputLen - outputLenUpdate, (B_ALGORITHM_OBJ)NULL_PTR, (A_SURRENDER_CTX *)NULL_PTR)) != 0) { PORT_SetError(SEC_ERROR_BAD_DATA); return SECFailure; } *outputLen = outputLenUpdate + outputLenFinal; return SECSuccess;}/******************************************************************************* BLAPI implementation of RSA******************************************************************************/static const SECItem defaultPublicExponent = { siBuffer, (unsigned char *)"\001\000\001", 3};static const B_ALGORITHM_METHOD *rsa_alg_chooser[] = { &AM_SHA_RANDOM, &AM_RSA_KEY_GEN, &AM_RSA_ENCRYPT, &AM_RSA_DECRYPT, &AM_RSA_CRT_ENCRYPT, &AM_RSA_CRT_DECRYPT, (B_ALGORITHM_METHOD *)NULL_PTR};static SECStatusrsaZFreePrivateKeyInfo(A_PKCS_RSA_PRIVATE_KEY *privateKeyInfo){ PORT_ZFree(privateKeyInfo->modulus.data, privateKeyInfo->modulus.len); PORT_ZFree(privateKeyInfo->publicExponent.data, privateKeyInfo->publicExponent.len); PORT_ZFree(privateKeyInfo->privateExponent.data, privateKeyInfo->privateExponent.len); PORT_ZFree(privateKeyInfo->prime[0].data, privateKeyInfo->prime[0].len); PORT_ZFree(privateKeyInfo->prime[1].data, privateKeyInfo->prime[1].len); PORT_ZFree(privateKeyInfo->primeExponent[0].data, privateKeyInfo->primeExponent[0].len); PORT_ZFree(privateKeyInfo->primeExponent[1].data, privateKeyInfo->primeExponent[1].len); PORT_ZFree(privateKeyInfo->coefficient.data, privateKeyInfo->coefficient.len); return SECSuccess;}static SECStatusrsaConvertKeyInfoToBLKey(A_PKCS_RSA_PRIVATE_KEY *keyInfo, RSAPrivateKey *key){ PRArenaPool *arena = key->arena; SECItem tmp; SECITEMFROMITEM(arena, key->modulus, keyInfo->modulus); SECITEMFROMITEM(arena, key->publicExponent, keyInfo->publicExponent); SECITEMFROMITEM(arena, key->privateExponent, keyInfo->privateExponent); SECITEMFROMITEM(arena, key->prime1, keyInfo->prime[0]); SECITEMFROMITEM(arena, key->prime2, keyInfo->prime[1]); SECITEMFROMITEM(arena, key->exponent1, keyInfo->primeExponent[0]); SECITEMFROMITEM(arena, key->exponent2, keyInfo->primeExponent[1]); SECITEMFROMITEM(arena, key->coefficient, keyInfo->coefficient); /* Version field is to be handled at a higher level. */ key->version.data = NULL; key->version.len = 0; return SECSuccess;loser: PORT_SetError(PR_OUT_OF_MEMORY_ERROR); return SECFailure;}static SECStatusrsaConvertBLKeyToKeyInfo(RSAPrivateKey *key, A_PKCS_RSA_PRIVATE_KEY *keyInfo){ ITEMFROMSECITEM(keyInfo->modulus, key->modulus); ITEMFROMSECITEM(keyInfo->publicExponent, key->publicExponent); ITEMFROMSECITEM(keyInfo->privateExponent, key->privateExponent); ITEMFROMSECITEM(keyInfo->prime[0], key->prime1); ITEMFROMSECITEM(keyInfo->prime[1], key->prime2); ITEMFROMSECITEM(keyInfo->primeExponent[0], key->exponent1); ITEMFROMSECITEM(keyInfo->primeExponent[1], key->exponent2); ITEMFROMSECITEM(keyInfo->coefficient, key->coefficient); return SECSuccess;}RSAPrivateKey *RSA_NewKey(int keySizeInBits, SECItem * publicExponent){ /* BLAPI */ RSAPrivateKey *privateKey; /* BSAFE */ A_RSA_KEY_GEN_PARAMS keygenParams; A_PKCS_RSA_PRIVATE_KEY *privateKeyInfo = (A_PKCS_RSA_PRIVATE_KEY *)NULL_PTR; B_ALGORITHM_OBJ keypairGenerator = (B_ALGORITHM_OBJ)NULL_PTR; B_ALGORITHM_OBJ randomAlgorithm = NULL; B_KEY_OBJ publicKeyObj = (B_KEY_OBJ)NULL_PTR; B_KEY_OBJ privateKeyObj = (B_KEY_OBJ)NULL_PTR; PRArenaPool *arena; int status; /* Allocate space for key structure. */ arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE); if (arena == NULL) { PORT_SetError(PR_OUT_OF_MEMORY_ERROR); goto loser; } privateKey = (RSAPrivateKey *)PORT_ArenaZAlloc(arena, sizeof(RSAPrivateKey)); if (privateKey == NULL) { PORT_SetError(PR_OUT_OF_MEMORY_ERROR); goto loser; } privateKey->arena = arena; randomAlgorithm = generateRandomAlgorithm(keySizeInBits / BITS_PER_BYTE, 0); if (randomAlgorithm == NULL_PTR) { PORT_SetError(PR_OUT_OF_MEMORY_ERROR); goto loser;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?