summaryrefslogtreecommitdiffhomepage
path: root/libtomcrypt/src/pk/rsa/rsa_verify_hash.c
diff options
context:
space:
mode:
Diffstat (limited to 'libtomcrypt/src/pk/rsa/rsa_verify_hash.c')
-rw-r--r--libtomcrypt/src/pk/rsa/rsa_verify_hash.c114
1 files changed, 70 insertions, 44 deletions
diff --git a/libtomcrypt/src/pk/rsa/rsa_verify_hash.c b/libtomcrypt/src/pk/rsa/rsa_verify_hash.c
index fe83690..b584696 100644
--- a/libtomcrypt/src/pk/rsa/rsa_verify_hash.c
+++ b/libtomcrypt/src/pk/rsa/rsa_verify_hash.c
@@ -5,25 +5,23 @@
*
* The library is free for all purposes without any express
* guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
*/
#include "tomcrypt.h"
/**
@file rsa_verify_hash.c
- RSA LTC_PKCS #1 v1.5 or v2 PSS signature verification, Tom St Denis and Andreas Lange
+ RSA PKCS #1 v1.5 or v2 PSS signature verification, Tom St Denis and Andreas Lange
*/
#ifdef LTC_MRSA
/**
- LTC_PKCS #1 de-sign then v1.5 or PSS depad
+ PKCS #1 de-sign then v1.5 or PSS depad
@param sig The signature data
@param siglen The length of the signature data (octets)
@param hash The hash of the message that was signed
@param hashlen The length of the hash of the message that was signed (octets)
- @param padding Type of padding (LTC_LTC_PKCS_1_PSS or LTC_LTC_PKCS_1_V1_5)
+ @param padding Type of padding (LTC_PKCS_1_PSS, LTC_PKCS_1_V1_5 or LTC_PKCS_1_V1_5_NA1)
@param hash_idx The index of the desired hash
@param saltlen The length of the salt used during signature
@param stat [out] The result of the signature comparison, 1==valid, 0==invalid
@@ -50,12 +48,13 @@ int rsa_verify_hash_ex(const unsigned char *sig, unsigned long siglen,
/* valid padding? */
- if ((padding != LTC_LTC_PKCS_1_V1_5) &&
- (padding != LTC_LTC_PKCS_1_PSS)) {
+ if ((padding != LTC_PKCS_1_V1_5) &&
+ (padding != LTC_PKCS_1_PSS) &&
+ (padding != LTC_PKCS_1_V1_5_NA1)) {
return CRYPT_PK_INVALID_PADDING;
}
- if (padding == LTC_LTC_PKCS_1_PSS) {
+ if (padding != LTC_PKCS_1_V1_5_NA1) {
/* valid hash ? */
if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
return err;
@@ -90,21 +89,21 @@ int rsa_verify_hash_ex(const unsigned char *sig, unsigned long siglen,
return CRYPT_INVALID_PACKET;
}
- if (padding == LTC_LTC_PKCS_1_PSS) {
+ if (padding == LTC_PKCS_1_PSS) {
/* PSS decode and verify it */
- err = pkcs_1_pss_decode(hash, hashlen, tmpbuf, x, saltlen, hash_idx, modulus_bitlen, stat);
+
+ if(modulus_bitlen%8 == 1){
+ err = pkcs_1_pss_decode(hash, hashlen, tmpbuf+1, x-1, saltlen, hash_idx, modulus_bitlen, stat);
+ }
+ else{
+ err = pkcs_1_pss_decode(hash, hashlen, tmpbuf, x, saltlen, hash_idx, modulus_bitlen, stat);
+ }
+
} else {
- /* LTC_PKCS #1 v1.5 decode it */
+ /* PKCS #1 v1.5 decode it */
unsigned char *out;
- unsigned long outlen, loid[16];
+ unsigned long outlen;
int decoded;
- ltc_asn1_list digestinfo[2], siginfo[2];
-
- /* not all hashes have OIDs... so sad */
- if (hash_descriptor[hash_idx].OIDlen == 0) {
- err = CRYPT_INVALID_ARG;
- goto bail_2;
- }
/* allocate temp buffer for decoded hash */
outlen = ((modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0)) - 3;
@@ -114,36 +113,63 @@ int rsa_verify_hash_ex(const unsigned char *sig, unsigned long siglen,
goto bail_2;
}
- if ((err = pkcs_1_v1_5_decode(tmpbuf, x, LTC_LTC_PKCS_1_EMSA, modulus_bitlen, out, &outlen, &decoded)) != CRYPT_OK) {
- XFREE(out);
+ if ((err = pkcs_1_v1_5_decode(tmpbuf, x, LTC_PKCS_1_EMSA, modulus_bitlen, out, &outlen, &decoded)) != CRYPT_OK) {
+ XFREE(out);
goto bail_2;
}
- /* now we must decode out[0...outlen-1] using ASN.1, test the OID and then test the hash */
- /* construct the SEQUENCE
- SEQUENCE {
- SEQUENCE {hashoid OID
- blah NULL
+ if (padding == LTC_PKCS_1_V1_5) {
+ unsigned long loid[16], reallen;
+ ltc_asn1_list digestinfo[2], siginfo[2];
+
+ /* not all hashes have OIDs... so sad */
+ if (hash_descriptor[hash_idx].OIDlen == 0) {
+ err = CRYPT_INVALID_ARG;
+ goto bail_2;
+ }
+
+ /* now we must decode out[0...outlen-1] using ASN.1, test the OID and then test the hash */
+ /* construct the SEQUENCE
+ SEQUENCE {
+ SEQUENCE {hashoid OID
+ blah NULL
+ }
+ hash OCTET STRING
+ }
+ */
+ LTC_SET_ASN1(digestinfo, 0, LTC_ASN1_OBJECT_IDENTIFIER, loid, sizeof(loid)/sizeof(loid[0]));
+ LTC_SET_ASN1(digestinfo, 1, LTC_ASN1_NULL, NULL, 0);
+ LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 2);
+ LTC_SET_ASN1(siginfo, 1, LTC_ASN1_OCTET_STRING, tmpbuf, siglen);
+
+ if ((err = der_decode_sequence(out, outlen, siginfo, 2)) != CRYPT_OK) {
+ /* fallback to Legacy:missing NULL */
+ LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 1);
+ if ((err = der_decode_sequence(out, outlen, siginfo, 2)) != CRYPT_OK) {
+ XFREE(out);
+ goto bail_2;
}
- hash OCTET STRING
}
- */
- LTC_SET_ASN1(digestinfo, 0, LTC_ASN1_OBJECT_IDENTIFIER, loid, sizeof(loid)/sizeof(loid[0]));
- LTC_SET_ASN1(digestinfo, 1, LTC_ASN1_NULL, NULL, 0);
- LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 2);
- LTC_SET_ASN1(siginfo, 1, LTC_ASN1_OCTET_STRING, tmpbuf, siglen);
-
- if ((err = der_decode_sequence(out, outlen, siginfo, 2)) != CRYPT_OK) {
- XFREE(out);
- goto bail_2;
- }
- /* test OID */
- if ((digestinfo[0].size == hash_descriptor[hash_idx].OIDlen) &&
+ if ((err = der_length_sequence(siginfo, 2, &reallen)) != CRYPT_OK) {
+ XFREE(out);
+ goto bail_2;
+ }
+
+ /* test OID */
+ if ((reallen == outlen) &&
+ (digestinfo[0].size == hash_descriptor[hash_idx].OIDlen) &&
(XMEMCMP(digestinfo[0].data, hash_descriptor[hash_idx].OID, sizeof(unsigned long) * hash_descriptor[hash_idx].OIDlen) == 0) &&
- (siginfo[1].size == hashlen) &&
+ (siginfo[1].size == hashlen) &&
(XMEMCMP(siginfo[1].data, hash, hashlen) == 0)) {
- *stat = 1;
+ *stat = 1;
+ }
+ } else {
+ /* only check if the hash is equal */
+ if ((hashlen == outlen) &&
+ (XMEMCMP(out, hash, hashlen) == 0)) {
+ *stat = 1;
+ }
}
#ifdef LTC_CLEAN_STACK
@@ -162,6 +188,6 @@ bail_2:
#endif /* LTC_MRSA */
-/* $Source$ */
-/* $Revision$ */
-/* $Date$ */
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */