pkcs1.c 7.3 KB

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