Index: nss/lib/softoken/pkcs11c.c |
=================================================================== |
--- nss/lib/softoken/pkcs11c.c (revision 239365) |
+++ nss/lib/softoken/pkcs11c.c (working copy) |
@@ -274,8 +274,34 @@ |
/* |
************** Crypto Functions: Utilities ************************ |
*/ |
+/* |
+ * Utility function for converting PSS/OAEP parameter types into |
+ * HASH_HashTypes. Note: Only SHA family functions are defined in RFC 3447. |
+ */ |
+static HASH_HashType |
+GetHashTypeFromMechanism(CK_MECHANISM_TYPE mech) |
+{ |
+ switch (mech) { |
+ case CKM_SHA_1: |
+ case CKG_MGF1_SHA1: |
+ return HASH_AlgSHA1; |
+ case CKM_SHA224: |
+ case CKG_MGF1_SHA224: |
+ return HASH_AlgSHA224; |
+ case CKM_SHA256: |
+ case CKG_MGF1_SHA256: |
+ return HASH_AlgSHA256; |
+ case CKM_SHA384: |
+ case CKG_MGF1_SHA384: |
+ return HASH_AlgSHA384; |
+ case CKM_SHA512: |
+ case CKG_MGF1_SHA512: |
+ return HASH_AlgSHA512; |
+ default: |
+ return HASH_AlgNULL; |
+ } |
+} |
- |
/* |
* return a context based on the SFTKContext type. |
*/ |
@@ -458,23 +484,154 @@ |
} |
static SECStatus |
-sftk_EncryptOAEP(SFTKOAEPEncryptInfo *info, unsigned char *output, |
- unsigned int *outputLen, unsigned int maxLen, |
- unsigned char *input, unsigned int inputLen) |
+sftk_RSAEncryptRaw(NSSLOWKEYPublicKey *key, unsigned char *output, |
+ unsigned int *outputLen, unsigned int maxLen, |
+ const unsigned char *input, unsigned int inputLen) |
{ |
- return RSA_EncryptOAEP(info->params, info->key, output, outputLen, |
- maxLen, input, inputLen); |
+ SECStatus rv = SECFailure; |
+ |
+ PORT_Assert(key->keyType == NSSLOWKEYRSAKey); |
+ if (key->keyType != NSSLOWKEYRSAKey) { |
+ PORT_SetError(SEC_ERROR_INVALID_KEY); |
+ return SECFailure; |
+ } |
+ |
+ rv = RSA_EncryptRaw(&key->u.rsa, output, outputLen, maxLen, input, |
+ inputLen); |
+ if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { |
+ sftk_fatalError = PR_TRUE; |
+ } |
+ |
+ return rv; |
} |
static SECStatus |
-sftk_DecryptOAEP(SFTKOAEPDecryptInfo *info, unsigned char *output, |
- unsigned int *outputLen, unsigned int maxLen, |
- unsigned char *input, unsigned int inputLen) |
+sftk_RSADecryptRaw(NSSLOWKEYPrivateKey *key, unsigned char *output, |
+ unsigned int *outputLen, unsigned int maxLen, |
+ const unsigned char *input, unsigned int inputLen) |
{ |
- return RSA_DecryptOAEP(info->params, info->key, output, outputLen, |
- maxLen, input, inputLen); |
+ SECStatus rv = SECFailure; |
+ |
+ PORT_Assert(key->keyType == NSSLOWKEYRSAKey); |
+ if (key->keyType != NSSLOWKEYRSAKey) { |
+ PORT_SetError(SEC_ERROR_INVALID_KEY); |
+ return SECFailure; |
+ } |
+ |
+ rv = RSA_DecryptRaw(&key->u.rsa, output, outputLen, maxLen, input, |
+ inputLen); |
+ if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { |
+ sftk_fatalError = PR_TRUE; |
+ } |
+ |
+ return rv; |
} |
+static SECStatus |
+sftk_RSAEncrypt(NSSLOWKEYPublicKey *key, unsigned char *output, |
+ unsigned int *outputLen, unsigned int maxLen, |
+ const unsigned char *input, unsigned int inputLen) |
+{ |
+ SECStatus rv = SECFailure; |
+ |
+ PORT_Assert(key->keyType == NSSLOWKEYRSAKey); |
+ if (key->keyType != NSSLOWKEYRSAKey) { |
+ PORT_SetError(SEC_ERROR_INVALID_KEY); |
+ return SECFailure; |
+ } |
+ |
+ rv = RSA_EncryptBlock(&key->u.rsa, output, outputLen, maxLen, input, |
+ inputLen); |
+ if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { |
+ sftk_fatalError = PR_TRUE; |
+ } |
+ |
+ return rv; |
+} |
+ |
+static SECStatus |
+sftk_RSADecrypt(NSSLOWKEYPrivateKey *key, unsigned char *output, |
+ unsigned int *outputLen, unsigned int maxLen, |
+ const unsigned char *input, unsigned int inputLen) |
+{ |
+ SECStatus rv = SECFailure; |
+ |
+ PORT_Assert(key->keyType == NSSLOWKEYRSAKey); |
+ if (key->keyType != NSSLOWKEYRSAKey) { |
+ PORT_SetError(SEC_ERROR_INVALID_KEY); |
+ return SECFailure; |
+ } |
+ |
+ rv = RSA_DecryptBlock(&key->u.rsa, output, outputLen, maxLen, input, |
+ inputLen); |
+ if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { |
+ sftk_fatalError = PR_TRUE; |
+ } |
+ |
+ return rv; |
+} |
+ |
+static SECStatus |
+sftk_RSAEncryptOAEP(SFTKOAEPEncryptInfo *info, unsigned char *output, |
+ unsigned int *outputLen, unsigned int maxLen, |
+ const unsigned char *input, unsigned int inputLen) |
+{ |
+ HASH_HashType hashAlg; |
+ HASH_HashType maskHashAlg; |
+ |
+ PORT_Assert(info->key->keyType == NSSLOWKEYRSAKey); |
+ if (info->key->keyType != NSSLOWKEYRSAKey) { |
+ PORT_SetError(SEC_ERROR_INVALID_KEY); |
+ return SECFailure; |
+ } |
+ |
+ hashAlg = GetHashTypeFromMechanism(info->params->hashAlg); |
+ maskHashAlg = GetHashTypeFromMechanism(info->params->mgf); |
+ |
+ if (info->params->source != CKZ_DATA_SPECIFIED) { |
+ PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); |
+ return SECFailure; |
+ } |
+ |
+ return RSA_EncryptOAEP(&info->key->u.rsa, hashAlg, maskHashAlg, |
+ (const unsigned char*)info->params->pSourceData, |
+ info->params->ulSourceDataLen, NULL, 0, |
+ output, outputLen, maxLen, input, inputLen); |
+} |
+ |
+static SECStatus |
+sftk_RSADecryptOAEP(SFTKOAEPDecryptInfo *info, unsigned char *output, |
+ unsigned int *outputLen, unsigned int maxLen, |
+ const unsigned char *input, unsigned int inputLen) |
+{ |
+ SECStatus rv = SECFailure; |
+ HASH_HashType hashAlg; |
+ HASH_HashType maskHashAlg; |
+ |
+ PORT_Assert(info->key->keyType == NSSLOWKEYRSAKey); |
+ if (info->key->keyType != NSSLOWKEYRSAKey) { |
+ PORT_SetError(SEC_ERROR_INVALID_KEY); |
+ return SECFailure; |
+ } |
+ |
+ hashAlg = GetHashTypeFromMechanism(info->params->hashAlg); |
+ maskHashAlg = GetHashTypeFromMechanism(info->params->mgf); |
+ |
+ if (info->params->source != CKZ_DATA_SPECIFIED) { |
+ PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); |
+ return SECFailure; |
+ } |
+ |
+ rv = RSA_DecryptOAEP(&info->key->u.rsa, hashAlg, maskHashAlg, |
+ (const unsigned char*)info->params->pSourceData, |
+ info->params->ulSourceDataLen, |
+ output, outputLen, maxLen, input, inputLen); |
+ if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { |
+ sftk_fatalError = PR_TRUE; |
+ } |
+ return rv; |
+} |
+ |
static SFTKChaCha20Poly1305Info * |
sftk_ChaCha20Poly1305_CreateContext(const unsigned char *key, |
unsigned int keyLen, |
@@ -629,7 +786,7 @@ |
context->cipherInfo = (void *)pubKey; |
context->update = (SFTKCipher) |
(pMechanism->mechanism == CKM_RSA_X_509 |
- ? RSA_EncryptRaw : RSA_EncryptBlock); |
+ ? sftk_RSAEncryptRaw : sftk_RSAEncrypt); |
} else { |
NSSLOWKEYPrivateKey *privKey = sftk_GetPrivKey(key,CKK_RSA,&crv); |
if (privKey == NULL) { |
@@ -640,7 +797,7 @@ |
context->cipherInfo = (void *)privKey; |
context->update = (SFTKCipher) |
(pMechanism->mechanism == CKM_RSA_X_509 |
- ? RSA_DecryptRaw : RSA_DecryptBlock); |
+ ? sftk_RSADecryptRaw : sftk_RSADecrypt); |
} |
context->destroy = sftk_Null; |
break; |
@@ -670,7 +827,7 @@ |
crv = CKR_KEY_HANDLE_INVALID; |
break; |
} |
- context->update = (SFTKCipher) sftk_EncryptOAEP; |
+ context->update = (SFTKCipher) sftk_RSAEncryptOAEP; |
context->maxLen = nsslowkey_PublicModulusLen(info->key); |
context->cipherInfo = info; |
} else { |
@@ -686,7 +843,7 @@ |
crv = CKR_KEY_HANDLE_INVALID; |
break; |
} |
- context->update = (SFTKCipher) sftk_DecryptOAEP; |
+ context->update = (SFTKCipher) sftk_RSADecryptOAEP; |
context->maxLen = nsslowkey_PrivateModulusLen(info->key); |
context->cipherInfo = info; |
} |
@@ -1291,18 +1448,22 @@ |
|| context->padDataLength == context->blockSize); |
+ if (context->doPad) { |
+ /* Check the data length for block ciphers. If we are padding, |
+ * then we must be using a block cipher. In the non-padding case |
+ * the error will be returned by the underlying decryption |
+ * function when we do the actual decrypt. We need to do the |
+ * check here to avoid returning a negative length to the caller |
+ * or reading before the beginning of the pEncryptedPart buffer. |
+ */ |
+ if ((ulEncryptedPartLen == 0) || |
+ (ulEncryptedPartLen % context->blockSize) != 0) { |
+ return CKR_ENCRYPTED_DATA_LEN_RANGE; |
+ } |
+ } |
+ |
if (!pPart) { |
if (context->doPad) { |
- /* we can check the data length here because if we are padding, |
- * then we must be using a block cipher. In the non-padding case |
- * the error will be returned by the underlying decryption |
- * function when do do the actual decrypt. We need to do the |
- * check here to avoid returning a negative length to the caller. |
- */ |
- if ((ulEncryptedPartLen == 0) || |
- (ulEncryptedPartLen % context->blockSize) != 0) { |
- return CKR_ENCRYPTED_DATA_LEN_RANGE; |
- } |
*pulPartLen = |
ulEncryptedPartLen + context->padDataLength - context->blockSize; |
return CKR_OK; |
@@ -2006,11 +2167,18 @@ |
* encode RSA PKCS #1 Signature data before signing... |
*/ |
static SECStatus |
-sftk_HashSign(SFTKHashSignInfo *info,unsigned char *sig,unsigned int *sigLen, |
- unsigned int maxLen,unsigned char *hash, unsigned int hashLen) |
+sftk_RSAHashSign(SFTKHashSignInfo *info, unsigned char *sig, |
+ unsigned int *sigLen, unsigned int maxLen, |
+ const unsigned char *hash, unsigned int hashLen) |
{ |
- return RSA_HashSign(info->hashOid,info->key,sig,sigLen,maxLen, |
- hash,hashLen); |
+ PORT_Assert(info->key->keyType == NSSLOWKEYRSAKey); |
+ if (info->key->keyType != NSSLOWKEYRSAKey) { |
+ PORT_SetError(SEC_ERROR_INVALID_KEY); |
+ return SECFailure; |
+ } |
+ |
+ return RSA_HashSign(info->hashOid, info->key, sig, sigLen, maxLen, |
+ hash, hashLen); |
} |
/* XXX Old template; want to expunge it eventually. */ |
@@ -2039,12 +2207,14 @@ |
{ 0, } |
}; |
+/* |
+ * encode RSA PKCS #1 Signature data before signing... |
+ */ |
SECStatus |
RSA_HashSign(SECOidTag hashOid, NSSLOWKEYPrivateKey *key, |
- unsigned char *sig, unsigned int *sigLen, unsigned int maxLen, |
- unsigned char *hash, unsigned int hashLen) |
+ unsigned char *sig, unsigned int *sigLen, unsigned int maxLen, |
+ const unsigned char *hash, unsigned int hashLen) |
{ |
- |
SECStatus rv = SECFailure; |
SECItem digder; |
PLArenaPool *arena = NULL; |
@@ -2053,41 +2223,111 @@ |
digder.data = NULL; |
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
- if ( !arena ) { goto loser; } |
- |
+ if (!arena) { |
+ goto loser; |
+ } |
+ |
/* Construct digest info */ |
di = SGN_CreateDigestInfo(hashOid, hash, hashLen); |
- if (!di) { goto loser; } |
+ if (!di) { |
+ goto loser; |
+ } |
/* Der encode the digest as a DigestInfo */ |
rv = DER_Encode(arena, &digder, SGNDigestInfoTemplate, di); |
if (rv != SECSuccess) { |
- goto loser; |
+ goto loser; |
} |
/* |
** Encrypt signature after constructing appropriate PKCS#1 signature |
** block |
*/ |
- rv = RSA_Sign(key,sig,sigLen,maxLen,digder.data,digder.len); |
+ rv = RSA_Sign(&key->u.rsa, sig, sigLen, maxLen, digder.data, |
+ digder.len); |
+ if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { |
+ sftk_fatalError = PR_TRUE; |
+ } |
loser: |
SGN_DestroyDigestInfo(di); |
if (arena != NULL) { |
- PORT_FreeArena(arena, PR_FALSE); |
+ PORT_FreeArena(arena, PR_FALSE); |
} |
return rv; |
} |
static SECStatus |
-sftk_SignPSS(SFTKHashSignInfo *info,unsigned char *sig,unsigned int *sigLen, |
- unsigned int maxLen,unsigned char *hash, unsigned int hashLen) |
+sftk_RSASign(NSSLOWKEYPrivateKey *key, unsigned char *output, |
+ unsigned int *outputLen, unsigned int maxOutputLen, |
+ const unsigned char *input, unsigned int inputLen) |
{ |
- return RSA_SignPSS(info->params,info->key,sig,sigLen,maxLen, |
- hash,hashLen); |
+ SECStatus rv = SECFailure; |
+ |
+ PORT_Assert(key->keyType == NSSLOWKEYRSAKey); |
+ if (key->keyType != NSSLOWKEYRSAKey) { |
+ PORT_SetError(SEC_ERROR_INVALID_KEY); |
+ return SECFailure; |
+ } |
+ |
+ rv = RSA_Sign(&key->u.rsa, output, outputLen, maxOutputLen, input, |
+ inputLen); |
+ if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { |
+ sftk_fatalError = PR_TRUE; |
+ } |
+ return rv; |
} |
static SECStatus |
+sftk_RSASignRaw(NSSLOWKEYPrivateKey *key, unsigned char *output, |
+ unsigned int *outputLen, unsigned int maxOutputLen, |
+ const unsigned char *input, unsigned int inputLen) |
+{ |
+ SECStatus rv = SECFailure; |
+ |
+ PORT_Assert(key->keyType == NSSLOWKEYRSAKey); |
+ if (key->keyType != NSSLOWKEYRSAKey) { |
+ PORT_SetError(SEC_ERROR_INVALID_KEY); |
+ return SECFailure; |
+ } |
+ |
+ rv = RSA_SignRaw(&key->u.rsa, output, outputLen, maxOutputLen, input, |
+ inputLen); |
+ if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { |
+ sftk_fatalError = PR_TRUE; |
+ } |
+ return rv; |
+ |
+} |
+ |
+static SECStatus |
+sftk_RSASignPSS(SFTKHashSignInfo *info, unsigned char *sig, |
+ unsigned int *sigLen, unsigned int maxLen, |
+ const unsigned char *hash, unsigned int hashLen) |
+{ |
+ SECStatus rv = SECFailure; |
+ HASH_HashType hashAlg; |
+ HASH_HashType maskHashAlg; |
+ CK_RSA_PKCS_PSS_PARAMS *params = (CK_RSA_PKCS_PSS_PARAMS *)info->params; |
+ |
+ PORT_Assert(info->key->keyType == NSSLOWKEYRSAKey); |
+ if (info->key->keyType != NSSLOWKEYRSAKey) { |
+ PORT_SetError(SEC_ERROR_INVALID_KEY); |
+ return SECFailure; |
+ } |
+ |
+ hashAlg = GetHashTypeFromMechanism(params->hashAlg); |
+ maskHashAlg = GetHashTypeFromMechanism(params->mgf); |
+ |
+ rv = RSA_SignPSS(&info->key->u.rsa, hashAlg, maskHashAlg, NULL, |
+ params->sLen, sig, sigLen, maxLen, hash, hashLen); |
+ if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { |
+ sftk_fatalError = PR_TRUE; |
+ } |
+ return rv; |
+} |
+ |
+static SECStatus |
nsc_DSA_Verify_Stub(void *ctx, void *sigBuf, unsigned int sigLen, |
void *dataBuf, unsigned int dataLen) |
{ |
@@ -2215,7 +2455,7 @@ |
context->multi = PR_TRUE; \ |
crv = sftk_doSub ## mmm (context); \ |
if (crv != CKR_OK) break; \ |
- context->update = (SFTKCipher) sftk_HashSign; \ |
+ context->update = (SFTKCipher) sftk_RSAHashSign; \ |
info = PORT_New(SFTKHashSignInfo); \ |
if (info == NULL) { crv = CKR_HOST_MEMORY; break; } \ |
info->hashOid = SEC_OID_ ## mmm ; \ |
@@ -2231,10 +2471,10 @@ |
INIT_RSA_SIGN_MECH(SHA512) |
case CKM_RSA_PKCS: |
- context->update = (SFTKCipher) RSA_Sign; |
+ context->update = (SFTKCipher) sftk_RSASign; |
goto finish_rsa; |
case CKM_RSA_X_509: |
- context->update = (SFTKCipher) RSA_SignRaw; |
+ context->update = (SFTKCipher) sftk_RSASignRaw; |
finish_rsa: |
if (key_type != CKK_RSA) { |
crv = CKR_KEY_TYPE_INCONSISTENT; |
@@ -2283,7 +2523,7 @@ |
} |
context->cipherInfo = info; |
context->destroy = (SFTKDestroy) sftk_Space; |
- context->update = (SFTKCipher) sftk_SignPSS; |
+ context->update = (SFTKCipher) sftk_RSASignPSS; |
context->maxLen = nsslowkey_PrivateModulusLen(info->key); |
break; |
@@ -2395,7 +2635,7 @@ |
context->hashUpdate = sftk_HMACConstantTime_Update; |
context->hashdestroy = sftk_MACConstantTime_DestroyContext; |
context->end = sftk_MACConstantTime_EndHash; |
- context->update = sftk_SignCopy; |
+ context->update = (SFTKCipher) sftk_SignCopy; |
context->destroy = sftk_Space; |
context->maxLen = 64; |
context->multi = PR_TRUE; |
@@ -2424,7 +2664,7 @@ |
context->hashUpdate = sftk_SSLv3MACConstantTime_Update; |
context->hashdestroy = sftk_MACConstantTime_DestroyContext; |
context->end = sftk_MACConstantTime_EndHash; |
- context->update = sftk_SignCopy; |
+ context->update = (SFTKCipher) sftk_SignCopy; |
context->destroy = sftk_Space; |
context->maxLen = 64; |
context->multi = PR_TRUE; |
@@ -2692,52 +2932,66 @@ |
/* Handle RSA Signature formatting */ |
static SECStatus |
-sftk_hashCheckSign(SFTKHashVerifyInfo *info, unsigned char *sig, |
- unsigned int sigLen, unsigned char *digest, unsigned int digestLen) |
+sftk_hashCheckSign(SFTKHashVerifyInfo *info, const unsigned char *sig, |
+ unsigned int sigLen, const unsigned char *digest, |
+ unsigned int digestLen) |
{ |
- return RSA_HashCheckSign(info->hashOid, info->key, sig, sigLen, |
- digest, digestLen); |
+ PORT_Assert(info->key->keyType == NSSLOWKEYRSAKey); |
+ if (info->key->keyType != NSSLOWKEYRSAKey) { |
+ PORT_SetError(SEC_ERROR_INVALID_KEY); |
+ return SECFailure; |
+ } |
+ |
+ return RSA_HashCheckSign(info->hashOid, info->key, sig, sigLen, digest, |
+ digestLen); |
} |
SECStatus |
RSA_HashCheckSign(SECOidTag hashOid, NSSLOWKEYPublicKey *key, |
- unsigned char *sig, unsigned int sigLen, |
- unsigned char *digest, unsigned int digestLen) |
+ const unsigned char *sig, unsigned int sigLen, |
+ const unsigned char *hash, unsigned int hashLen) |
{ |
- |
SECItem it; |
SGNDigestInfo *di = NULL; |
SECStatus rv = SECSuccess; |
- |
+ |
it.data = NULL; |
+ it.len = nsslowkey_PublicModulusLen(key); |
+ if (!it.len) { |
+ goto loser; |
+ } |
- if (key == NULL) goto loser; |
+ it.data = (unsigned char *)PORT_Alloc(it.len); |
+ if (it.data == NULL) { |
+ goto loser; |
+ } |
- it.len = nsslowkey_PublicModulusLen(key); |
- if (!it.len) goto loser; |
- |
- it.data = (unsigned char *) PORT_Alloc(it.len); |
- if (it.data == NULL) goto loser; |
- |
/* decrypt the block */ |
- rv = RSA_CheckSignRecover(key, it.data, &it.len, it.len, sig, sigLen); |
- if (rv != SECSuccess) goto loser; |
+ rv = RSA_CheckSignRecover(&key->u.rsa, it.data, &it.len, it.len, sig, |
+ sigLen); |
+ if (rv != SECSuccess) { |
+ goto loser; |
+ } |
di = SGN_DecodeDigestInfo(&it); |
- if (di == NULL) goto loser; |
- if (di->digest.len != digestLen) goto loser; |
+ if (di == NULL) { |
+ goto loser; |
+ } |
+ if (di->digest.len != hashLen) { |
+ goto loser; |
+ } |
/* make sure the tag is OK */ |
if (SECOID_GetAlgorithmTag(&di->digestAlgorithm) != hashOid) { |
- goto loser; |
+ goto loser; |
} |
/* make sure the "parameters" are not too bogus. */ |
if (di->digestAlgorithm.parameters.len > 2) { |
- goto loser; |
+ goto loser; |
} |
/* Now check the signature */ |
- if (PORT_Memcmp(digest, di->digest.data, di->digest.len) == 0) { |
- goto done; |
+ if (PORT_Memcmp(hash, di->digest.data, di->digest.len) == 0) { |
+ goto done; |
} |
loser: |
@@ -2745,20 +2999,66 @@ |
rv = SECFailure; |
done: |
- if (it.data != NULL) PORT_Free(it.data); |
- if (di != NULL) SGN_DestroyDigestInfo(di); |
- |
+ if (it.data != NULL) { |
+ PORT_Free(it.data); |
+ } |
+ if (di != NULL) { |
+ SGN_DestroyDigestInfo(di); |
+ } |
+ |
return rv; |
} |
static SECStatus |
-sftk_CheckSignPSS(SFTKHashVerifyInfo *info, unsigned char *sig, |
- unsigned int sigLen, unsigned char *digest, unsigned int digestLen) |
+sftk_RSACheckSign(NSSLOWKEYPublicKey *key, const unsigned char *sig, |
+ unsigned int sigLen, const unsigned char *digest, |
+ unsigned int digestLen) |
{ |
- return RSA_CheckSignPSS(info->params, info->key, sig, sigLen, |
- digest, digestLen); |
+ PORT_Assert(key->keyType == NSSLOWKEYRSAKey); |
+ if (key->keyType != NSSLOWKEYRSAKey) { |
+ PORT_SetError(SEC_ERROR_INVALID_KEY); |
+ return SECFailure; |
+ } |
+ |
+ return RSA_CheckSign(&key->u.rsa, sig, sigLen, digest, digestLen); |
} |
+static SECStatus |
+sftk_RSACheckSignRaw(NSSLOWKEYPublicKey *key, const unsigned char *sig, |
+ unsigned int sigLen, const unsigned char *digest, |
+ unsigned int digestLen) |
+{ |
+ PORT_Assert(key->keyType == NSSLOWKEYRSAKey); |
+ if (key->keyType != NSSLOWKEYRSAKey) { |
+ PORT_SetError(SEC_ERROR_INVALID_KEY); |
+ return SECFailure; |
+ } |
+ |
+ return RSA_CheckSignRaw(&key->u.rsa, sig, sigLen, digest, digestLen); |
+} |
+ |
+static SECStatus |
+sftk_RSACheckSignPSS(SFTKHashVerifyInfo *info, const unsigned char *sig, |
+ unsigned int sigLen, const unsigned char *digest, |
+ unsigned int digestLen) |
+{ |
+ HASH_HashType hashAlg; |
+ HASH_HashType maskHashAlg; |
+ CK_RSA_PKCS_PSS_PARAMS *params = (CK_RSA_PKCS_PSS_PARAMS *)info->params; |
+ |
+ PORT_Assert(info->key->keyType == NSSLOWKEYRSAKey); |
+ if (info->key->keyType != NSSLOWKEYRSAKey) { |
+ PORT_SetError(SEC_ERROR_INVALID_KEY); |
+ return SECFailure; |
+ } |
+ |
+ hashAlg = GetHashTypeFromMechanism(params->hashAlg); |
+ maskHashAlg = GetHashTypeFromMechanism(params->mgf); |
+ |
+ return RSA_CheckSignPSS(&info->key->u.rsa, hashAlg, maskHashAlg, |
+ params->sLen, sig, sigLen, digest, digestLen); |
+} |
+ |
/* NSC_VerifyInit initializes a verification operation, |
* where the signature is an appendix to the data, |
* and plaintext cannot be recovered from the signature (e.g. DSA) */ |
@@ -2811,10 +3111,10 @@ |
INIT_RSA_VFY_MECH(SHA512) |
case CKM_RSA_PKCS: |
- context->verify = (SFTKVerify) RSA_CheckSign; |
+ context->verify = (SFTKVerify) sftk_RSACheckSign; |
goto finish_rsa; |
case CKM_RSA_X_509: |
- context->verify = (SFTKVerify) RSA_CheckSignRaw; |
+ context->verify = (SFTKVerify) sftk_RSACheckSignRaw; |
finish_rsa: |
if (key_type != CKK_RSA) { |
if (info) PORT_Free(info); |
@@ -2860,7 +3160,7 @@ |
} |
context->cipherInfo = info; |
context->destroy = (SFTKDestroy) sftk_Space; |
- context->verify = (SFTKVerify) sftk_CheckSignPSS; |
+ context->verify = (SFTKVerify) sftk_RSACheckSignPSS; |
break; |
case CKM_DSA_SHA1: |
context->multi = PR_TRUE; |
@@ -3040,7 +3340,36 @@ |
/* |
************** Crypto Functions: Verify Recover ************************ |
*/ |
+static SECStatus |
+sftk_RSACheckSignRecover(NSSLOWKEYPublicKey *key, unsigned char *data, |
+ unsigned int *dataLen, unsigned int maxDataLen, |
+ const unsigned char *sig, unsigned int sigLen) |
+{ |
+ PORT_Assert(key->keyType == NSSLOWKEYRSAKey); |
+ if (key->keyType != NSSLOWKEYRSAKey) { |
+ PORT_SetError(SEC_ERROR_INVALID_KEY); |
+ return SECFailure; |
+ } |
+ return RSA_CheckSignRecover(&key->u.rsa, data, dataLen, maxDataLen, |
+ sig, sigLen); |
+} |
+ |
+static SECStatus |
+sftk_RSACheckSignRecoverRaw(NSSLOWKEYPublicKey *key, unsigned char *data, |
+ unsigned int *dataLen, unsigned int maxDataLen, |
+ const unsigned char *sig, unsigned int sigLen) |
+{ |
+ PORT_Assert(key->keyType == NSSLOWKEYRSAKey); |
+ if (key->keyType != NSSLOWKEYRSAKey) { |
+ PORT_SetError(SEC_ERROR_INVALID_KEY); |
+ return SECFailure; |
+ } |
+ |
+ return RSA_CheckSignRecoverRaw(&key->u.rsa, data, dataLen, maxDataLen, |
+ sig, sigLen); |
+} |
+ |
/* NSC_VerifyRecoverInit initializes a signature verification operation, |
* where the data is recovered from the signature. |
* E.g. Decryption with the user's public key */ |
@@ -3082,7 +3411,7 @@ |
} |
context->cipherInfo = pubKey; |
context->update = (SFTKCipher) (pMechanism->mechanism == CKM_RSA_X_509 |
- ? RSA_CheckSignRecoverRaw : RSA_CheckSignRecover); |
+ ? sftk_RSACheckSignRecoverRaw : sftk_RSACheckSignRecover); |
context->destroy = sftk_Null; |
break; |
default: |