1*03f9172cSAndroid Build Coastguard Worker /*
2*03f9172cSAndroid Build Coastguard Worker * PKCS #1 (RSA Encryption)
3*03f9172cSAndroid Build Coastguard Worker * Copyright (c) 2006-2014, Jouni Malinen <[email protected]>
4*03f9172cSAndroid Build Coastguard Worker *
5*03f9172cSAndroid Build Coastguard Worker * This software may be distributed under the terms of the BSD license.
6*03f9172cSAndroid Build Coastguard Worker * See README for more details.
7*03f9172cSAndroid Build Coastguard Worker */
8*03f9172cSAndroid Build Coastguard Worker
9*03f9172cSAndroid Build Coastguard Worker #include "includes.h"
10*03f9172cSAndroid Build Coastguard Worker
11*03f9172cSAndroid Build Coastguard Worker #include "common.h"
12*03f9172cSAndroid Build Coastguard Worker #include "crypto/crypto.h"
13*03f9172cSAndroid Build Coastguard Worker #include "rsa.h"
14*03f9172cSAndroid Build Coastguard Worker #include "asn1.h"
15*03f9172cSAndroid Build Coastguard Worker #include "pkcs1.h"
16*03f9172cSAndroid Build Coastguard Worker
17*03f9172cSAndroid Build Coastguard Worker
pkcs1_generate_encryption_block(u8 block_type,size_t modlen,const u8 * in,size_t inlen,u8 * out,size_t * outlen)18*03f9172cSAndroid Build Coastguard Worker static int pkcs1_generate_encryption_block(u8 block_type, size_t modlen,
19*03f9172cSAndroid Build Coastguard Worker const u8 *in, size_t inlen,
20*03f9172cSAndroid Build Coastguard Worker u8 *out, size_t *outlen)
21*03f9172cSAndroid Build Coastguard Worker {
22*03f9172cSAndroid Build Coastguard Worker size_t ps_len;
23*03f9172cSAndroid Build Coastguard Worker u8 *pos;
24*03f9172cSAndroid Build Coastguard Worker
25*03f9172cSAndroid Build Coastguard Worker /*
26*03f9172cSAndroid Build Coastguard Worker * PKCS #1 v1.5, 8.1:
27*03f9172cSAndroid Build Coastguard Worker *
28*03f9172cSAndroid Build Coastguard Worker * EB = 00 || BT || PS || 00 || D
29*03f9172cSAndroid Build Coastguard Worker * BT = 00 or 01 for private-key operation; 02 for public-key operation
30*03f9172cSAndroid Build Coastguard Worker * PS = k-3-||D||; at least eight octets
31*03f9172cSAndroid Build Coastguard Worker * (BT=0: PS=0x00, BT=1: PS=0xff, BT=2: PS=pseudorandom non-zero)
32*03f9172cSAndroid Build Coastguard Worker * k = length of modulus in octets (modlen)
33*03f9172cSAndroid Build Coastguard Worker */
34*03f9172cSAndroid Build Coastguard Worker
35*03f9172cSAndroid Build Coastguard Worker if (modlen < 12 || modlen > *outlen || inlen > modlen - 11) {
36*03f9172cSAndroid Build Coastguard Worker wpa_printf(MSG_DEBUG, "PKCS #1: %s - Invalid buffer "
37*03f9172cSAndroid Build Coastguard Worker "lengths (modlen=%lu outlen=%lu inlen=%lu)",
38*03f9172cSAndroid Build Coastguard Worker __func__, (unsigned long) modlen,
39*03f9172cSAndroid Build Coastguard Worker (unsigned long) *outlen,
40*03f9172cSAndroid Build Coastguard Worker (unsigned long) inlen);
41*03f9172cSAndroid Build Coastguard Worker return -1;
42*03f9172cSAndroid Build Coastguard Worker }
43*03f9172cSAndroid Build Coastguard Worker
44*03f9172cSAndroid Build Coastguard Worker pos = out;
45*03f9172cSAndroid Build Coastguard Worker *pos++ = 0x00;
46*03f9172cSAndroid Build Coastguard Worker *pos++ = block_type; /* BT */
47*03f9172cSAndroid Build Coastguard Worker ps_len = modlen - inlen - 3;
48*03f9172cSAndroid Build Coastguard Worker switch (block_type) {
49*03f9172cSAndroid Build Coastguard Worker case 0:
50*03f9172cSAndroid Build Coastguard Worker os_memset(pos, 0x00, ps_len);
51*03f9172cSAndroid Build Coastguard Worker pos += ps_len;
52*03f9172cSAndroid Build Coastguard Worker break;
53*03f9172cSAndroid Build Coastguard Worker case 1:
54*03f9172cSAndroid Build Coastguard Worker os_memset(pos, 0xff, ps_len);
55*03f9172cSAndroid Build Coastguard Worker pos += ps_len;
56*03f9172cSAndroid Build Coastguard Worker break;
57*03f9172cSAndroid Build Coastguard Worker case 2:
58*03f9172cSAndroid Build Coastguard Worker if (os_get_random(pos, ps_len) < 0) {
59*03f9172cSAndroid Build Coastguard Worker wpa_printf(MSG_DEBUG, "PKCS #1: %s - Failed to get "
60*03f9172cSAndroid Build Coastguard Worker "random data for PS", __func__);
61*03f9172cSAndroid Build Coastguard Worker return -1;
62*03f9172cSAndroid Build Coastguard Worker }
63*03f9172cSAndroid Build Coastguard Worker while (ps_len--) {
64*03f9172cSAndroid Build Coastguard Worker if (*pos == 0x00)
65*03f9172cSAndroid Build Coastguard Worker *pos = 0x01;
66*03f9172cSAndroid Build Coastguard Worker pos++;
67*03f9172cSAndroid Build Coastguard Worker }
68*03f9172cSAndroid Build Coastguard Worker break;
69*03f9172cSAndroid Build Coastguard Worker default:
70*03f9172cSAndroid Build Coastguard Worker wpa_printf(MSG_DEBUG, "PKCS #1: %s - Unsupported block type "
71*03f9172cSAndroid Build Coastguard Worker "%d", __func__, block_type);
72*03f9172cSAndroid Build Coastguard Worker return -1;
73*03f9172cSAndroid Build Coastguard Worker }
74*03f9172cSAndroid Build Coastguard Worker *pos++ = 0x00;
75*03f9172cSAndroid Build Coastguard Worker os_memcpy(pos, in, inlen); /* D */
76*03f9172cSAndroid Build Coastguard Worker
77*03f9172cSAndroid Build Coastguard Worker return 0;
78*03f9172cSAndroid Build Coastguard Worker }
79*03f9172cSAndroid Build Coastguard Worker
80*03f9172cSAndroid Build Coastguard Worker
pkcs1_encrypt(int block_type,struct crypto_rsa_key * key,int use_private,const u8 * in,size_t inlen,u8 * out,size_t * outlen)81*03f9172cSAndroid Build Coastguard Worker int pkcs1_encrypt(int block_type, struct crypto_rsa_key *key,
82*03f9172cSAndroid Build Coastguard Worker int use_private, const u8 *in, size_t inlen,
83*03f9172cSAndroid Build Coastguard Worker u8 *out, size_t *outlen)
84*03f9172cSAndroid Build Coastguard Worker {
85*03f9172cSAndroid Build Coastguard Worker size_t modlen;
86*03f9172cSAndroid Build Coastguard Worker
87*03f9172cSAndroid Build Coastguard Worker modlen = crypto_rsa_get_modulus_len(key);
88*03f9172cSAndroid Build Coastguard Worker
89*03f9172cSAndroid Build Coastguard Worker if (pkcs1_generate_encryption_block(block_type, modlen, in, inlen,
90*03f9172cSAndroid Build Coastguard Worker out, outlen) < 0)
91*03f9172cSAndroid Build Coastguard Worker return -1;
92*03f9172cSAndroid Build Coastguard Worker
93*03f9172cSAndroid Build Coastguard Worker return crypto_rsa_exptmod(out, modlen, out, outlen, key, use_private);
94*03f9172cSAndroid Build Coastguard Worker }
95*03f9172cSAndroid Build Coastguard Worker
96*03f9172cSAndroid Build Coastguard Worker
pkcs1_v15_private_key_decrypt(struct crypto_rsa_key * key,const u8 * in,size_t inlen,u8 * out,size_t * outlen)97*03f9172cSAndroid Build Coastguard Worker int pkcs1_v15_private_key_decrypt(struct crypto_rsa_key *key,
98*03f9172cSAndroid Build Coastguard Worker const u8 *in, size_t inlen,
99*03f9172cSAndroid Build Coastguard Worker u8 *out, size_t *outlen)
100*03f9172cSAndroid Build Coastguard Worker {
101*03f9172cSAndroid Build Coastguard Worker int res;
102*03f9172cSAndroid Build Coastguard Worker u8 *pos, *end;
103*03f9172cSAndroid Build Coastguard Worker
104*03f9172cSAndroid Build Coastguard Worker res = crypto_rsa_exptmod(in, inlen, out, outlen, key, 1);
105*03f9172cSAndroid Build Coastguard Worker if (res)
106*03f9172cSAndroid Build Coastguard Worker return res;
107*03f9172cSAndroid Build Coastguard Worker
108*03f9172cSAndroid Build Coastguard Worker if (*outlen < 2 || out[0] != 0 || out[1] != 2)
109*03f9172cSAndroid Build Coastguard Worker return -1;
110*03f9172cSAndroid Build Coastguard Worker
111*03f9172cSAndroid Build Coastguard Worker /* Skip PS (pseudorandom non-zero octets) */
112*03f9172cSAndroid Build Coastguard Worker pos = out + 2;
113*03f9172cSAndroid Build Coastguard Worker end = out + *outlen;
114*03f9172cSAndroid Build Coastguard Worker while (*pos && pos < end)
115*03f9172cSAndroid Build Coastguard Worker pos++;
116*03f9172cSAndroid Build Coastguard Worker if (pos == end)
117*03f9172cSAndroid Build Coastguard Worker return -1;
118*03f9172cSAndroid Build Coastguard Worker if (pos - out - 2 < 8) {
119*03f9172cSAndroid Build Coastguard Worker /* PKCS #1 v1.5, 8.1: At least eight octets long PS */
120*03f9172cSAndroid Build Coastguard Worker wpa_printf(MSG_INFO, "LibTomCrypt: Too short padding");
121*03f9172cSAndroid Build Coastguard Worker return -1;
122*03f9172cSAndroid Build Coastguard Worker }
123*03f9172cSAndroid Build Coastguard Worker pos++;
124*03f9172cSAndroid Build Coastguard Worker
125*03f9172cSAndroid Build Coastguard Worker *outlen -= pos - out;
126*03f9172cSAndroid Build Coastguard Worker
127*03f9172cSAndroid Build Coastguard Worker /* Strip PKCS #1 header */
128*03f9172cSAndroid Build Coastguard Worker os_memmove(out, pos, *outlen);
129*03f9172cSAndroid Build Coastguard Worker
130*03f9172cSAndroid Build Coastguard Worker return 0;
131*03f9172cSAndroid Build Coastguard Worker }
132*03f9172cSAndroid Build Coastguard Worker
133*03f9172cSAndroid Build Coastguard Worker
pkcs1_decrypt_public_key(struct crypto_rsa_key * key,const u8 * crypt,size_t crypt_len,u8 * plain,size_t * plain_len)134*03f9172cSAndroid Build Coastguard Worker int pkcs1_decrypt_public_key(struct crypto_rsa_key *key,
135*03f9172cSAndroid Build Coastguard Worker const u8 *crypt, size_t crypt_len,
136*03f9172cSAndroid Build Coastguard Worker u8 *plain, size_t *plain_len)
137*03f9172cSAndroid Build Coastguard Worker {
138*03f9172cSAndroid Build Coastguard Worker size_t len;
139*03f9172cSAndroid Build Coastguard Worker u8 *pos;
140*03f9172cSAndroid Build Coastguard Worker
141*03f9172cSAndroid Build Coastguard Worker len = *plain_len;
142*03f9172cSAndroid Build Coastguard Worker if (crypto_rsa_exptmod(crypt, crypt_len, plain, &len, key, 0) < 0)
143*03f9172cSAndroid Build Coastguard Worker return -1;
144*03f9172cSAndroid Build Coastguard Worker
145*03f9172cSAndroid Build Coastguard Worker /*
146*03f9172cSAndroid Build Coastguard Worker * PKCS #1 v1.5, 8.1:
147*03f9172cSAndroid Build Coastguard Worker *
148*03f9172cSAndroid Build Coastguard Worker * EB = 00 || BT || PS || 00 || D
149*03f9172cSAndroid Build Coastguard Worker * BT = 00 or 01
150*03f9172cSAndroid Build Coastguard Worker * PS = k-3-||D|| times (00 if BT=00) or (FF if BT=01)
151*03f9172cSAndroid Build Coastguard Worker * k = length of modulus in octets
152*03f9172cSAndroid Build Coastguard Worker *
153*03f9172cSAndroid Build Coastguard Worker * Based on 10.1.3, "The block type shall be 01" for a signature.
154*03f9172cSAndroid Build Coastguard Worker */
155*03f9172cSAndroid Build Coastguard Worker
156*03f9172cSAndroid Build Coastguard Worker if (len < 3 + 8 + 16 /* min hash len */ ||
157*03f9172cSAndroid Build Coastguard Worker plain[0] != 0x00 || plain[1] != 0x01) {
158*03f9172cSAndroid Build Coastguard Worker wpa_printf(MSG_INFO, "LibTomCrypt: Invalid signature EB "
159*03f9172cSAndroid Build Coastguard Worker "structure");
160*03f9172cSAndroid Build Coastguard Worker wpa_hexdump_key(MSG_DEBUG, "Signature EB", plain, len);
161*03f9172cSAndroid Build Coastguard Worker return -1;
162*03f9172cSAndroid Build Coastguard Worker }
163*03f9172cSAndroid Build Coastguard Worker
164*03f9172cSAndroid Build Coastguard Worker pos = plain + 3;
165*03f9172cSAndroid Build Coastguard Worker /* BT = 01 */
166*03f9172cSAndroid Build Coastguard Worker if (plain[2] != 0xff) {
167*03f9172cSAndroid Build Coastguard Worker wpa_printf(MSG_INFO, "LibTomCrypt: Invalid signature "
168*03f9172cSAndroid Build Coastguard Worker "PS (BT=01)");
169*03f9172cSAndroid Build Coastguard Worker wpa_hexdump_key(MSG_DEBUG, "Signature EB", plain, len);
170*03f9172cSAndroid Build Coastguard Worker return -1;
171*03f9172cSAndroid Build Coastguard Worker }
172*03f9172cSAndroid Build Coastguard Worker while (pos < plain + len && *pos == 0xff)
173*03f9172cSAndroid Build Coastguard Worker pos++;
174*03f9172cSAndroid Build Coastguard Worker
175*03f9172cSAndroid Build Coastguard Worker if (pos - plain - 2 < 8) {
176*03f9172cSAndroid Build Coastguard Worker /* PKCS #1 v1.5, 8.1: At least eight octets long PS */
177*03f9172cSAndroid Build Coastguard Worker wpa_printf(MSG_INFO, "LibTomCrypt: Too short signature "
178*03f9172cSAndroid Build Coastguard Worker "padding");
179*03f9172cSAndroid Build Coastguard Worker wpa_hexdump_key(MSG_DEBUG, "Signature EB", plain, len);
180*03f9172cSAndroid Build Coastguard Worker return -1;
181*03f9172cSAndroid Build Coastguard Worker }
182*03f9172cSAndroid Build Coastguard Worker
183*03f9172cSAndroid Build Coastguard Worker if (pos + 16 /* min hash len */ >= plain + len || *pos != 0x00) {
184*03f9172cSAndroid Build Coastguard Worker wpa_printf(MSG_INFO, "LibTomCrypt: Invalid signature EB "
185*03f9172cSAndroid Build Coastguard Worker "structure (2)");
186*03f9172cSAndroid Build Coastguard Worker wpa_hexdump_key(MSG_DEBUG, "Signature EB", plain, len);
187*03f9172cSAndroid Build Coastguard Worker return -1;
188*03f9172cSAndroid Build Coastguard Worker }
189*03f9172cSAndroid Build Coastguard Worker pos++;
190*03f9172cSAndroid Build Coastguard Worker len -= pos - plain;
191*03f9172cSAndroid Build Coastguard Worker
192*03f9172cSAndroid Build Coastguard Worker /* Strip PKCS #1 header */
193*03f9172cSAndroid Build Coastguard Worker os_memmove(plain, pos, len);
194*03f9172cSAndroid Build Coastguard Worker *plain_len = len;
195*03f9172cSAndroid Build Coastguard Worker
196*03f9172cSAndroid Build Coastguard Worker return 0;
197*03f9172cSAndroid Build Coastguard Worker }
198*03f9172cSAndroid Build Coastguard Worker
199*03f9172cSAndroid Build Coastguard Worker
pkcs1_v15_sig_ver(struct crypto_public_key * pk,const u8 * s,size_t s_len,const struct asn1_oid * hash_alg,const u8 * hash,size_t hash_len)200*03f9172cSAndroid Build Coastguard Worker int pkcs1_v15_sig_ver(struct crypto_public_key *pk,
201*03f9172cSAndroid Build Coastguard Worker const u8 *s, size_t s_len,
202*03f9172cSAndroid Build Coastguard Worker const struct asn1_oid *hash_alg,
203*03f9172cSAndroid Build Coastguard Worker const u8 *hash, size_t hash_len)
204*03f9172cSAndroid Build Coastguard Worker {
205*03f9172cSAndroid Build Coastguard Worker int res;
206*03f9172cSAndroid Build Coastguard Worker u8 *decrypted;
207*03f9172cSAndroid Build Coastguard Worker size_t decrypted_len;
208*03f9172cSAndroid Build Coastguard Worker const u8 *pos, *end, *next, *da_end;
209*03f9172cSAndroid Build Coastguard Worker struct asn1_hdr hdr;
210*03f9172cSAndroid Build Coastguard Worker struct asn1_oid oid;
211*03f9172cSAndroid Build Coastguard Worker
212*03f9172cSAndroid Build Coastguard Worker decrypted = os_malloc(s_len);
213*03f9172cSAndroid Build Coastguard Worker if (decrypted == NULL)
214*03f9172cSAndroid Build Coastguard Worker return -1;
215*03f9172cSAndroid Build Coastguard Worker decrypted_len = s_len;
216*03f9172cSAndroid Build Coastguard Worker res = crypto_public_key_decrypt_pkcs1(pk, s, s_len, decrypted,
217*03f9172cSAndroid Build Coastguard Worker &decrypted_len);
218*03f9172cSAndroid Build Coastguard Worker if (res < 0) {
219*03f9172cSAndroid Build Coastguard Worker wpa_printf(MSG_INFO, "PKCS #1: RSA decrypt failed");
220*03f9172cSAndroid Build Coastguard Worker os_free(decrypted);
221*03f9172cSAndroid Build Coastguard Worker return -1;
222*03f9172cSAndroid Build Coastguard Worker }
223*03f9172cSAndroid Build Coastguard Worker wpa_hexdump(MSG_DEBUG, "Decrypted(S)", decrypted, decrypted_len);
224*03f9172cSAndroid Build Coastguard Worker
225*03f9172cSAndroid Build Coastguard Worker /*
226*03f9172cSAndroid Build Coastguard Worker * PKCS #1 v1.5, 10.1.2:
227*03f9172cSAndroid Build Coastguard Worker *
228*03f9172cSAndroid Build Coastguard Worker * DigestInfo ::= SEQUENCE {
229*03f9172cSAndroid Build Coastguard Worker * digestAlgorithm DigestAlgorithmIdentifier,
230*03f9172cSAndroid Build Coastguard Worker * digest Digest
231*03f9172cSAndroid Build Coastguard Worker * }
232*03f9172cSAndroid Build Coastguard Worker *
233*03f9172cSAndroid Build Coastguard Worker * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
234*03f9172cSAndroid Build Coastguard Worker *
235*03f9172cSAndroid Build Coastguard Worker * Digest ::= OCTET STRING
236*03f9172cSAndroid Build Coastguard Worker *
237*03f9172cSAndroid Build Coastguard Worker */
238*03f9172cSAndroid Build Coastguard Worker if (asn1_get_next(decrypted, decrypted_len, &hdr) < 0 ||
239*03f9172cSAndroid Build Coastguard Worker !asn1_is_sequence(&hdr)) {
240*03f9172cSAndroid Build Coastguard Worker asn1_unexpected(&hdr,
241*03f9172cSAndroid Build Coastguard Worker "PKCS #1: Expected SEQUENCE (DigestInfo)");
242*03f9172cSAndroid Build Coastguard Worker os_free(decrypted);
243*03f9172cSAndroid Build Coastguard Worker return -1;
244*03f9172cSAndroid Build Coastguard Worker }
245*03f9172cSAndroid Build Coastguard Worker wpa_hexdump(MSG_MSGDUMP, "PKCS #1: DigestInfo",
246*03f9172cSAndroid Build Coastguard Worker hdr.payload, hdr.length);
247*03f9172cSAndroid Build Coastguard Worker
248*03f9172cSAndroid Build Coastguard Worker pos = hdr.payload;
249*03f9172cSAndroid Build Coastguard Worker end = pos + hdr.length;
250*03f9172cSAndroid Build Coastguard Worker
251*03f9172cSAndroid Build Coastguard Worker /*
252*03f9172cSAndroid Build Coastguard Worker * X.509:
253*03f9172cSAndroid Build Coastguard Worker * AlgorithmIdentifier ::= SEQUENCE {
254*03f9172cSAndroid Build Coastguard Worker * algorithm OBJECT IDENTIFIER,
255*03f9172cSAndroid Build Coastguard Worker * parameters ANY DEFINED BY algorithm OPTIONAL
256*03f9172cSAndroid Build Coastguard Worker * }
257*03f9172cSAndroid Build Coastguard Worker */
258*03f9172cSAndroid Build Coastguard Worker
259*03f9172cSAndroid Build Coastguard Worker if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
260*03f9172cSAndroid Build Coastguard Worker !asn1_is_sequence(&hdr)) {
261*03f9172cSAndroid Build Coastguard Worker asn1_unexpected(&hdr,
262*03f9172cSAndroid Build Coastguard Worker "PKCS #1: Expected SEQUENCE (AlgorithmIdentifier)");
263*03f9172cSAndroid Build Coastguard Worker os_free(decrypted);
264*03f9172cSAndroid Build Coastguard Worker return -1;
265*03f9172cSAndroid Build Coastguard Worker }
266*03f9172cSAndroid Build Coastguard Worker wpa_hexdump(MSG_MSGDUMP, "PKCS #1: DigestAlgorithmIdentifier",
267*03f9172cSAndroid Build Coastguard Worker hdr.payload, hdr.length);
268*03f9172cSAndroid Build Coastguard Worker da_end = hdr.payload + hdr.length;
269*03f9172cSAndroid Build Coastguard Worker
270*03f9172cSAndroid Build Coastguard Worker if (asn1_get_oid(hdr.payload, hdr.length, &oid, &next)) {
271*03f9172cSAndroid Build Coastguard Worker wpa_printf(MSG_DEBUG,
272*03f9172cSAndroid Build Coastguard Worker "PKCS #1: Failed to parse digestAlgorithm");
273*03f9172cSAndroid Build Coastguard Worker os_free(decrypted);
274*03f9172cSAndroid Build Coastguard Worker return -1;
275*03f9172cSAndroid Build Coastguard Worker }
276*03f9172cSAndroid Build Coastguard Worker wpa_hexdump(MSG_MSGDUMP, "PKCS #1: Digest algorithm parameters",
277*03f9172cSAndroid Build Coastguard Worker next, da_end - next);
278*03f9172cSAndroid Build Coastguard Worker
279*03f9172cSAndroid Build Coastguard Worker /*
280*03f9172cSAndroid Build Coastguard Worker * RFC 5754: The correct encoding for the SHA2 algorithms would be to
281*03f9172cSAndroid Build Coastguard Worker * omit the parameters, but there are implementation that encode these
282*03f9172cSAndroid Build Coastguard Worker * as a NULL element. Allow these two cases and reject anything else.
283*03f9172cSAndroid Build Coastguard Worker */
284*03f9172cSAndroid Build Coastguard Worker if (da_end > next &&
285*03f9172cSAndroid Build Coastguard Worker (asn1_get_next(next, da_end - next, &hdr) < 0 ||
286*03f9172cSAndroid Build Coastguard Worker !asn1_is_null(&hdr) ||
287*03f9172cSAndroid Build Coastguard Worker hdr.payload + hdr.length != da_end)) {
288*03f9172cSAndroid Build Coastguard Worker wpa_printf(MSG_DEBUG,
289*03f9172cSAndroid Build Coastguard Worker "PKCS #1: Unexpected digest algorithm parameters");
290*03f9172cSAndroid Build Coastguard Worker os_free(decrypted);
291*03f9172cSAndroid Build Coastguard Worker return -1;
292*03f9172cSAndroid Build Coastguard Worker }
293*03f9172cSAndroid Build Coastguard Worker
294*03f9172cSAndroid Build Coastguard Worker if (!asn1_oid_equal(&oid, hash_alg)) {
295*03f9172cSAndroid Build Coastguard Worker char txt[100], txt2[100];
296*03f9172cSAndroid Build Coastguard Worker asn1_oid_to_str(&oid, txt, sizeof(txt));
297*03f9172cSAndroid Build Coastguard Worker asn1_oid_to_str(hash_alg, txt2, sizeof(txt2));
298*03f9172cSAndroid Build Coastguard Worker wpa_printf(MSG_DEBUG,
299*03f9172cSAndroid Build Coastguard Worker "PKCS #1: Hash alg OID mismatch: was %s, expected %s",
300*03f9172cSAndroid Build Coastguard Worker txt, txt2);
301*03f9172cSAndroid Build Coastguard Worker os_free(decrypted);
302*03f9172cSAndroid Build Coastguard Worker return -1;
303*03f9172cSAndroid Build Coastguard Worker }
304*03f9172cSAndroid Build Coastguard Worker
305*03f9172cSAndroid Build Coastguard Worker /* Digest ::= OCTET STRING */
306*03f9172cSAndroid Build Coastguard Worker pos = da_end;
307*03f9172cSAndroid Build Coastguard Worker
308*03f9172cSAndroid Build Coastguard Worker if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
309*03f9172cSAndroid Build Coastguard Worker !asn1_is_octetstring(&hdr)) {
310*03f9172cSAndroid Build Coastguard Worker asn1_unexpected(&hdr,
311*03f9172cSAndroid Build Coastguard Worker "PKCS #1: Expected OCTETSTRING (Digest)");
312*03f9172cSAndroid Build Coastguard Worker os_free(decrypted);
313*03f9172cSAndroid Build Coastguard Worker return -1;
314*03f9172cSAndroid Build Coastguard Worker }
315*03f9172cSAndroid Build Coastguard Worker wpa_hexdump(MSG_MSGDUMP, "PKCS #1: Decrypted Digest",
316*03f9172cSAndroid Build Coastguard Worker hdr.payload, hdr.length);
317*03f9172cSAndroid Build Coastguard Worker
318*03f9172cSAndroid Build Coastguard Worker if (hdr.length != hash_len ||
319*03f9172cSAndroid Build Coastguard Worker os_memcmp_const(hdr.payload, hash, hdr.length) != 0) {
320*03f9172cSAndroid Build Coastguard Worker wpa_printf(MSG_INFO, "PKCS #1: Digest value does not match calculated hash");
321*03f9172cSAndroid Build Coastguard Worker os_free(decrypted);
322*03f9172cSAndroid Build Coastguard Worker return -1;
323*03f9172cSAndroid Build Coastguard Worker }
324*03f9172cSAndroid Build Coastguard Worker
325*03f9172cSAndroid Build Coastguard Worker if (hdr.payload + hdr.length != decrypted + decrypted_len) {
326*03f9172cSAndroid Build Coastguard Worker wpa_printf(MSG_INFO,
327*03f9172cSAndroid Build Coastguard Worker "PKCS #1: Extra data after signature - reject");
328*03f9172cSAndroid Build Coastguard Worker
329*03f9172cSAndroid Build Coastguard Worker wpa_hexdump(MSG_DEBUG, "PKCS #1: Extra data",
330*03f9172cSAndroid Build Coastguard Worker hdr.payload + hdr.length,
331*03f9172cSAndroid Build Coastguard Worker decrypted + decrypted_len - hdr.payload -
332*03f9172cSAndroid Build Coastguard Worker hdr.length);
333*03f9172cSAndroid Build Coastguard Worker
334*03f9172cSAndroid Build Coastguard Worker os_free(decrypted);
335*03f9172cSAndroid Build Coastguard Worker return -1;
336*03f9172cSAndroid Build Coastguard Worker }
337*03f9172cSAndroid Build Coastguard Worker
338*03f9172cSAndroid Build Coastguard Worker os_free(decrypted);
339*03f9172cSAndroid Build Coastguard Worker
340*03f9172cSAndroid Build Coastguard Worker return 0;
341*03f9172cSAndroid Build Coastguard Worker }
342