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 + -
显示快捷键?