18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * PKCS #1 (RSA Encryption) 350b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * Copyright (c) 2006-2014, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 1250b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt#include "crypto/crypto.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "rsa.h" 1450b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt#include "asn1.h" 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "pkcs1.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int pkcs1_generate_encryption_block(u8 block_type, size_t modlen, 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in, size_t inlen, 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *out, size_t *outlen) 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t ps_len; 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *pos; 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * PKCS #1 v1.5, 8.1: 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EB = 00 || BT || PS || 00 || D 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * BT = 00 or 01 for private-key operation; 02 for public-key operation 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * PS = k-3-||D||; at least eight octets 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * (BT=0: PS=0x00, BT=1: PS=0xff, BT=2: PS=pseudorandom non-zero) 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * k = length of modulus in octets (modlen) 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (modlen < 12 || modlen > *outlen || inlen > modlen - 11) { 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "PKCS #1: %s - Invalid buffer " 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "lengths (modlen=%lu outlen=%lu inlen=%lu)", 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__, (unsigned long) modlen, 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) *outlen, 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) inlen); 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = out; 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = 0x00; 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = block_type; /* BT */ 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ps_len = modlen - inlen - 3; 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (block_type) { 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 0: 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(pos, 0x00, ps_len); 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ps_len; 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 1: 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(pos, 0xff, ps_len); 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ps_len; 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 2: 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_get_random(pos, ps_len) < 0) { 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "PKCS #1: %s - Failed to get " 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "random data for PS", __func__); 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (ps_len--) { 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos == 0x00) 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos = 0x01; 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "PKCS #1: %s - Unsupported block type " 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%d", __func__, block_type); 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = 0x00; 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(pos, in, inlen); /* D */ 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint pkcs1_encrypt(int block_type, struct crypto_rsa_key *key, 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int use_private, const u8 *in, size_t inlen, 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *out, size_t *outlen) 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t modlen; 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt modlen = crypto_rsa_get_modulus_len(key); 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pkcs1_generate_encryption_block(block_type, modlen, in, inlen, 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out, outlen) < 0) 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return crypto_rsa_exptmod(out, modlen, out, outlen, key, use_private); 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint pkcs1_v15_private_key_decrypt(struct crypto_rsa_key *key, 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in, size_t inlen, 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *out, size_t *outlen) 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *pos, *end; 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = crypto_rsa_exptmod(in, inlen, out, outlen, key, 1); 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res) 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*outlen < 2 || out[0] != 0 || out[1] != 2) 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Skip PS (pseudorandom non-zero octets) */ 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = out + 2; 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = out + *outlen; 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (*pos && pos < end) 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos == end) 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11850b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt if (pos - out - 2 < 8) { 11950b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt /* PKCS #1 v1.5, 8.1: At least eight octets long PS */ 12050b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt wpa_printf(MSG_INFO, "LibTomCrypt: Too short padding"); 12150b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt return -1; 12250b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt } 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *outlen -= pos - out; 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Strip PKCS #1 header */ 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memmove(out, pos, *outlen); 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint pkcs1_decrypt_public_key(struct crypto_rsa_key *key, 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *crypt, size_t crypt_len, 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *plain, size_t *plain_len) 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len; 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *pos; 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = *plain_len; 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (crypto_rsa_exptmod(crypt, crypt_len, plain, &len, key, 0) < 0) 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * PKCS #1 v1.5, 8.1: 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EB = 00 || BT || PS || 00 || D 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * BT = 00 or 01 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * PS = k-3-||D|| times (00 if BT=00) or (FF if BT=01) 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * k = length of modulus in octets 15250b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * 15350b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * Based on 10.1.3, "The block type shall be 01" for a signature. 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 3 + 8 + 16 /* min hash len */ || 15750b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt plain[0] != 0x00 || plain[1] != 0x01) { 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "LibTomCrypt: Invalid signature EB " 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "structure"); 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = plain + 3; 16450b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt /* BT = 01 */ 16550b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt if (plain[2] != 0xff) { 16650b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt wpa_printf(MSG_INFO, "LibTomCrypt: Invalid signature " 16750b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt "PS (BT=01)"); 16850b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt return -1; 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17050b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt while (pos < plain + len && *pos == 0xff) 17150b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt pos++; 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos - plain - 2 < 8) { 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* PKCS #1 v1.5, 8.1: At least eight octets long PS */ 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "LibTomCrypt: Too short signature " 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "padding"); 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos + 16 /* min hash len */ >= plain + len || *pos != 0x00) { 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "LibTomCrypt: Invalid signature EB " 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "structure (2)"); 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len -= pos - plain; 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Strip PKCS #1 header */ 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memmove(plain, pos, len); 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *plain_len = len; 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19450b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt 19550b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt 19650b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidtint pkcs1_v15_sig_ver(struct crypto_public_key *pk, 19750b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt const u8 *s, size_t s_len, 19850b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt const struct asn1_oid *hash_alg, 19950b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt const u8 *hash, size_t hash_len) 20050b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt{ 20150b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt int res; 20250b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt u8 *decrypted; 20350b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt size_t decrypted_len; 20450b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt const u8 *pos, *end, *next, *da_end; 20550b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt struct asn1_hdr hdr; 20650b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt struct asn1_oid oid; 20750b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt 20850b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt decrypted = os_malloc(s_len); 20950b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt if (decrypted == NULL) 21050b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt return -1; 21150b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt decrypted_len = s_len; 21250b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt res = crypto_public_key_decrypt_pkcs1(pk, s, s_len, decrypted, 21350b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt &decrypted_len); 21450b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt if (res < 0) { 21550b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt wpa_printf(MSG_INFO, "PKCS #1: RSA decrypt failed"); 21650b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt os_free(decrypted); 21750b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt return -1; 21850b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt } 21950b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "Decrypted(S)", decrypted, decrypted_len); 22050b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt 22150b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt /* 22250b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * PKCS #1 v1.5, 10.1.2: 22350b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * 22450b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * DigestInfo ::= SEQUENCE { 22550b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * digestAlgorithm DigestAlgorithmIdentifier, 22650b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * digest Digest 22750b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * } 22850b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * 22950b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * DigestAlgorithmIdentifier ::= AlgorithmIdentifier 23050b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * 23150b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * Digest ::= OCTET STRING 23250b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * 23350b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt */ 23450b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt if (asn1_get_next(decrypted, decrypted_len, &hdr) < 0 || 23550b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt hdr.class != ASN1_CLASS_UNIVERSAL || 23650b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt hdr.tag != ASN1_TAG_SEQUENCE) { 23750b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt wpa_printf(MSG_DEBUG, 23850b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt "PKCS #1: Expected SEQUENCE (DigestInfo) - found class %d tag 0x%x", 23950b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt hdr.class, hdr.tag); 24050b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt os_free(decrypted); 24150b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt return -1; 24250b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt } 24350b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt 24450b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt pos = hdr.payload; 24550b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt end = pos + hdr.length; 24650b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt 24750b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt /* 24850b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * X.509: 24950b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * AlgorithmIdentifier ::= SEQUENCE { 25050b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * algorithm OBJECT IDENTIFIER, 25150b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * parameters ANY DEFINED BY algorithm OPTIONAL 25250b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * } 25350b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt */ 25450b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt 25550b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt if (asn1_get_next(pos, end - pos, &hdr) < 0 || 25650b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt hdr.class != ASN1_CLASS_UNIVERSAL || 25750b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt hdr.tag != ASN1_TAG_SEQUENCE) { 25850b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt wpa_printf(MSG_DEBUG, 25950b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt "PKCS #1: Expected SEQUENCE (AlgorithmIdentifier) - found class %d tag 0x%x", 26050b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt hdr.class, hdr.tag); 26150b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt os_free(decrypted); 26250b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt return -1; 26350b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt } 26450b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt da_end = hdr.payload + hdr.length; 26550b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt 26650b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt if (asn1_get_oid(hdr.payload, hdr.length, &oid, &next)) { 26750b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt wpa_printf(MSG_DEBUG, 26850b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt "PKCS #1: Failed to parse digestAlgorithm"); 26950b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt os_free(decrypted); 27050b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt return -1; 27150b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt } 27250b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt 27350b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt if (!asn1_oid_equal(&oid, hash_alg)) { 27450b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt char txt[100], txt2[100]; 27550b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt asn1_oid_to_str(&oid, txt, sizeof(txt)); 27650b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt asn1_oid_to_str(hash_alg, txt2, sizeof(txt2)); 27750b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt wpa_printf(MSG_DEBUG, 27850b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt "PKCS #1: Hash alg OID mismatch: was %s, expected %s", 27950b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt txt, txt2); 28050b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt os_free(decrypted); 28150b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt return -1; 28250b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt } 28350b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt 28450b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt /* Digest ::= OCTET STRING */ 28550b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt pos = da_end; 28650b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt end = decrypted + decrypted_len; 28750b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt 28850b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt if (asn1_get_next(pos, end - pos, &hdr) < 0 || 28950b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt hdr.class != ASN1_CLASS_UNIVERSAL || 29050b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt hdr.tag != ASN1_TAG_OCTETSTRING) { 29150b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt wpa_printf(MSG_DEBUG, 29250b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt "PKCS #1: Expected OCTETSTRING (Digest) - found class %d tag 0x%x", 29350b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt hdr.class, hdr.tag); 29450b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt os_free(decrypted); 29550b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt return -1; 29650b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt } 29750b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "PKCS #1: Decrypted Digest", 29850b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt hdr.payload, hdr.length); 29950b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt 30050b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt if (hdr.length != hash_len || 301c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt os_memcmp_const(hdr.payload, hash, hdr.length) != 0) { 30250b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt wpa_printf(MSG_INFO, "PKCS #1: Digest value does not match calculated hash"); 30350b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt os_free(decrypted); 30450b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt return -1; 30550b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt } 30650b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt 30750b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt os_free(decrypted); 30850b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt 30950b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt if (hdr.payload + hdr.length != end) { 31050b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt wpa_printf(MSG_INFO, 31150b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt "PKCS #1: Extra data after signature - reject"); 31250b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt 31350b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "PKCS #1: Extra data", 31450b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt hdr.payload + hdr.length, 31550b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt end - hdr.payload - hdr.length); 31650b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt return -1; 31750b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt } 31850b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt 31950b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt return 0; 32050b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt} 321