comparison libtomcrypt/src/pk/rsa/rsa_verify_hash.c @ 1471:6dba84798cd5

Update to libtomcrypt 1.18.1, merged with Dropbear changes
author Matt Johnston <matt@ucc.asn.au>
date Fri, 09 Feb 2018 21:44:05 +0800
parents f849a5ca2efc
children
comparison
equal deleted inserted replaced
1470:8bba51a55704 1471:6dba84798cd5
3 * LibTomCrypt is a library that provides various cryptographic 3 * LibTomCrypt is a library that provides various cryptographic
4 * algorithms in a highly modular and flexible manner. 4 * algorithms in a highly modular and flexible manner.
5 * 5 *
6 * The library is free for all purposes without any express 6 * The library is free for all purposes without any express
7 * guarantee it works. 7 * guarantee it works.
8 *
9 * Tom St Denis, [email protected], http://libtom.org
10 */ 8 */
11 #include "tomcrypt.h" 9 #include "tomcrypt.h"
12 10
13 /** 11 /**
14 @file rsa_verify_hash.c 12 @file rsa_verify_hash.c
15 RSA LTC_PKCS #1 v1.5 or v2 PSS signature verification, Tom St Denis and Andreas Lange 13 RSA PKCS #1 v1.5 or v2 PSS signature verification, Tom St Denis and Andreas Lange
16 */ 14 */
17 15
18 #ifdef LTC_MRSA 16 #ifdef LTC_MRSA
19 17
20 /** 18 /**
21 LTC_PKCS #1 de-sign then v1.5 or PSS depad 19 PKCS #1 de-sign then v1.5 or PSS depad
22 @param sig The signature data 20 @param sig The signature data
23 @param siglen The length of the signature data (octets) 21 @param siglen The length of the signature data (octets)
24 @param hash The hash of the message that was signed 22 @param hash The hash of the message that was signed
25 @param hashlen The length of the hash of the message that was signed (octets) 23 @param hashlen The length of the hash of the message that was signed (octets)
26 @param padding Type of padding (LTC_LTC_PKCS_1_PSS or LTC_LTC_PKCS_1_V1_5) 24 @param padding Type of padding (LTC_PKCS_1_PSS, LTC_PKCS_1_V1_5 or LTC_PKCS_1_V1_5_NA1)
27 @param hash_idx The index of the desired hash 25 @param hash_idx The index of the desired hash
28 @param saltlen The length of the salt used during signature 26 @param saltlen The length of the salt used during signature
29 @param stat [out] The result of the signature comparison, 1==valid, 0==invalid 27 @param stat [out] The result of the signature comparison, 1==valid, 0==invalid
30 @param key The public RSA key corresponding to the key that performed the signature 28 @param key The public RSA key corresponding to the key that performed the signature
31 @return CRYPT_OK on success (even if the signature is invalid) 29 @return CRYPT_OK on success (even if the signature is invalid)
48 /* default to invalid */ 46 /* default to invalid */
49 *stat = 0; 47 *stat = 0;
50 48
51 /* valid padding? */ 49 /* valid padding? */
52 50
53 if ((padding != LTC_LTC_PKCS_1_V1_5) && 51 if ((padding != LTC_PKCS_1_V1_5) &&
54 (padding != LTC_LTC_PKCS_1_PSS)) { 52 (padding != LTC_PKCS_1_PSS) &&
53 (padding != LTC_PKCS_1_V1_5_NA1)) {
55 return CRYPT_PK_INVALID_PADDING; 54 return CRYPT_PK_INVALID_PADDING;
56 } 55 }
57 56
58 if (padding == LTC_LTC_PKCS_1_PSS) { 57 if (padding != LTC_PKCS_1_V1_5_NA1) {
59 /* valid hash ? */ 58 /* valid hash ? */
60 if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { 59 if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
61 return err; 60 return err;
62 } 61 }
63 } 62 }
88 if (x != siglen) { 87 if (x != siglen) {
89 XFREE(tmpbuf); 88 XFREE(tmpbuf);
90 return CRYPT_INVALID_PACKET; 89 return CRYPT_INVALID_PACKET;
91 } 90 }
92 91
93 if (padding == LTC_LTC_PKCS_1_PSS) { 92 if (padding == LTC_PKCS_1_PSS) {
94 /* PSS decode and verify it */ 93 /* PSS decode and verify it */
95 err = pkcs_1_pss_decode(hash, hashlen, tmpbuf, x, saltlen, hash_idx, modulus_bitlen, stat); 94
95 if(modulus_bitlen%8 == 1){
96 err = pkcs_1_pss_decode(hash, hashlen, tmpbuf+1, x-1, saltlen, hash_idx, modulus_bitlen, stat);
97 }
98 else{
99 err = pkcs_1_pss_decode(hash, hashlen, tmpbuf, x, saltlen, hash_idx, modulus_bitlen, stat);
100 }
101
96 } else { 102 } else {
97 /* LTC_PKCS #1 v1.5 decode it */ 103 /* PKCS #1 v1.5 decode it */
98 unsigned char *out; 104 unsigned char *out;
99 unsigned long outlen, loid[16]; 105 unsigned long outlen;
100 int decoded; 106 int decoded;
101 ltc_asn1_list digestinfo[2], siginfo[2];
102
103 /* not all hashes have OIDs... so sad */
104 if (hash_descriptor[hash_idx].OIDlen == 0) {
105 err = CRYPT_INVALID_ARG;
106 goto bail_2;
107 }
108 107
109 /* allocate temp buffer for decoded hash */ 108 /* allocate temp buffer for decoded hash */
110 outlen = ((modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0)) - 3; 109 outlen = ((modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0)) - 3;
111 out = XMALLOC(outlen); 110 out = XMALLOC(outlen);
112 if (out == NULL) { 111 if (out == NULL) {
113 err = CRYPT_MEM; 112 err = CRYPT_MEM;
114 goto bail_2; 113 goto bail_2;
115 } 114 }
116 115
117 if ((err = pkcs_1_v1_5_decode(tmpbuf, x, LTC_LTC_PKCS_1_EMSA, modulus_bitlen, out, &outlen, &decoded)) != CRYPT_OK) { 116 if ((err = pkcs_1_v1_5_decode(tmpbuf, x, LTC_PKCS_1_EMSA, modulus_bitlen, out, &outlen, &decoded)) != CRYPT_OK) {
118 XFREE(out); 117 XFREE(out);
119 goto bail_2; 118 goto bail_2;
120 } 119 }
121 120
122 /* now we must decode out[0...outlen-1] using ASN.1, test the OID and then test the hash */ 121 if (padding == LTC_PKCS_1_V1_5) {
123 /* construct the SEQUENCE 122 unsigned long loid[16], reallen;
124 SEQUENCE { 123 ltc_asn1_list digestinfo[2], siginfo[2];
125 SEQUENCE {hashoid OID 124
126 blah NULL 125 /* not all hashes have OIDs... so sad */
126 if (hash_descriptor[hash_idx].OIDlen == 0) {
127 err = CRYPT_INVALID_ARG;
128 goto bail_2;
129 }
130
131 /* now we must decode out[0...outlen-1] using ASN.1, test the OID and then test the hash */
132 /* construct the SEQUENCE
133 SEQUENCE {
134 SEQUENCE {hashoid OID
135 blah NULL
136 }
137 hash OCTET STRING
138 }
139 */
140 LTC_SET_ASN1(digestinfo, 0, LTC_ASN1_OBJECT_IDENTIFIER, loid, sizeof(loid)/sizeof(loid[0]));
141 LTC_SET_ASN1(digestinfo, 1, LTC_ASN1_NULL, NULL, 0);
142 LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 2);
143 LTC_SET_ASN1(siginfo, 1, LTC_ASN1_OCTET_STRING, tmpbuf, siglen);
144
145 if ((err = der_decode_sequence(out, outlen, siginfo, 2)) != CRYPT_OK) {
146 /* fallback to Legacy:missing NULL */
147 LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 1);
148 if ((err = der_decode_sequence(out, outlen, siginfo, 2)) != CRYPT_OK) {
149 XFREE(out);
150 goto bail_2;
127 } 151 }
128 hash OCTET STRING
129 } 152 }
130 */
131 LTC_SET_ASN1(digestinfo, 0, LTC_ASN1_OBJECT_IDENTIFIER, loid, sizeof(loid)/sizeof(loid[0]));
132 LTC_SET_ASN1(digestinfo, 1, LTC_ASN1_NULL, NULL, 0);
133 LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 2);
134 LTC_SET_ASN1(siginfo, 1, LTC_ASN1_OCTET_STRING, tmpbuf, siglen);
135
136 if ((err = der_decode_sequence(out, outlen, siginfo, 2)) != CRYPT_OK) {
137 XFREE(out);
138 goto bail_2;
139 }
140 153
141 /* test OID */ 154 if ((err = der_length_sequence(siginfo, 2, &reallen)) != CRYPT_OK) {
142 if ((digestinfo[0].size == hash_descriptor[hash_idx].OIDlen) && 155 XFREE(out);
156 goto bail_2;
157 }
158
159 /* test OID */
160 if ((reallen == outlen) &&
161 (digestinfo[0].size == hash_descriptor[hash_idx].OIDlen) &&
143 (XMEMCMP(digestinfo[0].data, hash_descriptor[hash_idx].OID, sizeof(unsigned long) * hash_descriptor[hash_idx].OIDlen) == 0) && 162 (XMEMCMP(digestinfo[0].data, hash_descriptor[hash_idx].OID, sizeof(unsigned long) * hash_descriptor[hash_idx].OIDlen) == 0) &&
144 (siginfo[1].size == hashlen) && 163 (siginfo[1].size == hashlen) &&
145 (XMEMCMP(siginfo[1].data, hash, hashlen) == 0)) { 164 (XMEMCMP(siginfo[1].data, hash, hashlen) == 0)) {
146 *stat = 1; 165 *stat = 1;
166 }
167 } else {
168 /* only check if the hash is equal */
169 if ((hashlen == outlen) &&
170 (XMEMCMP(out, hash, hashlen) == 0)) {
171 *stat = 1;
172 }
147 } 173 }
148 174
149 #ifdef LTC_CLEAN_STACK 175 #ifdef LTC_CLEAN_STACK
150 zeromem(out, outlen); 176 zeromem(out, outlen);
151 #endif 177 #endif
160 return err; 186 return err;
161 } 187 }
162 188
163 #endif /* LTC_MRSA */ 189 #endif /* LTC_MRSA */
164 190
165 /* $Source$ */ 191 /* ref: $Format:%D$ */
166 /* $Revision$ */ 192 /* git commit: $Format:%H$ */
167 /* $Date$ */ 193 /* commit time: $Format:%ai$ */