1 /* 2 * WPA Supplicant / Crypto wrapper for internal crypto implementation 3 * Copyright (c) 2006-2007, Jouni Malinen <j@w1.fi> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 * 9 * Alternatively, this software may be distributed under the terms of BSD 10 * license. 11 * 12 * See README and COPYING for more details. 13 */ 14 15 #include "includes.h" 16 17 #include "common.h" 18 #include "crypto.h" 19 #include "md5.h" 20 #include "sha1.h" 21 #include "rc4.h" 22 #include "aes.h" 23 #include "tls/rsa.h" 24 #include "tls/bignum.h" 25 #include "tls/asn1.h" 26 27 28 #ifdef CONFIG_CRYPTO_INTERNAL 29 30 #ifdef CONFIG_TLS_INTERNAL 31 32 /* from des.c */ 33 struct des3_key_s { 34 u32 ek[3][32]; 35 u32 dk[3][32]; 36 }; 37 38 void des3_key_setup(const u8 *key, struct des3_key_s *dkey); 39 void des3_encrypt(const u8 *plain, const struct des3_key_s *key, u8 *crypt); 40 void des3_decrypt(const u8 *crypt, const struct des3_key_s *key, u8 *plain); 41 42 43 struct MD5Context { 44 u32 buf[4]; 45 u32 bits[2]; 46 u8 in[64]; 47 }; 48 49 struct SHA1Context { 50 u32 state[5]; 51 u32 count[2]; 52 unsigned char buffer[64]; 53 }; 54 55 56 struct crypto_hash { 57 enum crypto_hash_alg alg; 58 union { 59 struct MD5Context md5; 60 struct SHA1Context sha1; 61 } u; 62 u8 key[64]; 63 size_t key_len; 64 }; 65 66 67 struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key, 68 size_t key_len) 69 { 70 struct crypto_hash *ctx; 71 u8 k_pad[64]; 72 u8 tk[20]; 73 size_t i; 74 75 ctx = os_zalloc(sizeof(*ctx)); 76 if (ctx == NULL) 77 return NULL; 78 79 ctx->alg = alg; 80 81 switch (alg) { 82 case CRYPTO_HASH_ALG_MD5: 83 MD5Init(&ctx->u.md5); 84 break; 85 case CRYPTO_HASH_ALG_SHA1: 86 SHA1Init(&ctx->u.sha1); 87 break; 88 case CRYPTO_HASH_ALG_HMAC_MD5: 89 if (key_len > sizeof(k_pad)) { 90 MD5Init(&ctx->u.md5); 91 MD5Update(&ctx->u.md5, key, key_len); 92 MD5Final(tk, &ctx->u.md5); 93 key = tk; 94 key_len = 16; 95 } 96 os_memcpy(ctx->key, key, key_len); 97 ctx->key_len = key_len; 98 99 os_memcpy(k_pad, key, key_len); 100 os_memset(k_pad + key_len, 0, sizeof(k_pad) - key_len); 101 for (i = 0; i < sizeof(k_pad); i++) 102 k_pad[i] ^= 0x36; 103 MD5Init(&ctx->u.md5); 104 MD5Update(&ctx->u.md5, k_pad, sizeof(k_pad)); 105 break; 106 case CRYPTO_HASH_ALG_HMAC_SHA1: 107 if (key_len > sizeof(k_pad)) { 108 SHA1Init(&ctx->u.sha1); 109 SHA1Update(&ctx->u.sha1, key, key_len); 110 SHA1Final(tk, &ctx->u.sha1); 111 key = tk; 112 key_len = 20; 113 } 114 os_memcpy(ctx->key, key, key_len); 115 ctx->key_len = key_len; 116 117 os_memcpy(k_pad, key, key_len); 118 os_memset(k_pad + key_len, 0, sizeof(k_pad) - key_len); 119 for (i = 0; i < sizeof(k_pad); i++) 120 k_pad[i] ^= 0x36; 121 SHA1Init(&ctx->u.sha1); 122 SHA1Update(&ctx->u.sha1, k_pad, sizeof(k_pad)); 123 break; 124 default: 125 os_free(ctx); 126 return NULL; 127 } 128 129 return ctx; 130 } 131 132 133 void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len) 134 { 135 if (ctx == NULL) 136 return; 137 138 switch (ctx->alg) { 139 case CRYPTO_HASH_ALG_MD5: 140 case CRYPTO_HASH_ALG_HMAC_MD5: 141 MD5Update(&ctx->u.md5, data, len); 142 break; 143 case CRYPTO_HASH_ALG_SHA1: 144 case CRYPTO_HASH_ALG_HMAC_SHA1: 145 SHA1Update(&ctx->u.sha1, data, len); 146 break; 147 } 148 } 149 150 151 int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len) 152 { 153 u8 k_pad[64]; 154 size_t i; 155 156 if (ctx == NULL) 157 return -2; 158 159 if (mac == NULL || len == NULL) { 160 os_free(ctx); 161 return 0; 162 } 163 164 switch (ctx->alg) { 165 case CRYPTO_HASH_ALG_MD5: 166 if (*len < 16) { 167 *len = 16; 168 os_free(ctx); 169 return -1; 170 } 171 *len = 16; 172 MD5Final(mac, &ctx->u.md5); 173 break; 174 case CRYPTO_HASH_ALG_SHA1: 175 if (*len < 20) { 176 *len = 20; 177 os_free(ctx); 178 return -1; 179 } 180 *len = 20; 181 SHA1Final(mac, &ctx->u.sha1); 182 break; 183 case CRYPTO_HASH_ALG_HMAC_MD5: 184 if (*len < 16) { 185 *len = 16; 186 os_free(ctx); 187 return -1; 188 } 189 *len = 16; 190 191 MD5Final(mac, &ctx->u.md5); 192 193 os_memcpy(k_pad, ctx->key, ctx->key_len); 194 os_memset(k_pad + ctx->key_len, 0, 195 sizeof(k_pad) - ctx->key_len); 196 for (i = 0; i < sizeof(k_pad); i++) 197 k_pad[i] ^= 0x5c; 198 MD5Init(&ctx->u.md5); 199 MD5Update(&ctx->u.md5, k_pad, sizeof(k_pad)); 200 MD5Update(&ctx->u.md5, mac, 16); 201 MD5Final(mac, &ctx->u.md5); 202 break; 203 case CRYPTO_HASH_ALG_HMAC_SHA1: 204 if (*len < 20) { 205 *len = 20; 206 os_free(ctx); 207 return -1; 208 } 209 *len = 20; 210 211 SHA1Final(mac, &ctx->u.sha1); 212 213 os_memcpy(k_pad, ctx->key, ctx->key_len); 214 os_memset(k_pad + ctx->key_len, 0, 215 sizeof(k_pad) - ctx->key_len); 216 for (i = 0; i < sizeof(k_pad); i++) 217 k_pad[i] ^= 0x5c; 218 SHA1Init(&ctx->u.sha1); 219 SHA1Update(&ctx->u.sha1, k_pad, sizeof(k_pad)); 220 SHA1Update(&ctx->u.sha1, mac, 20); 221 SHA1Final(mac, &ctx->u.sha1); 222 break; 223 } 224 225 os_free(ctx); 226 227 return 0; 228 } 229 230 231 struct crypto_cipher { 232 enum crypto_cipher_alg alg; 233 union { 234 struct { 235 size_t used_bytes; 236 u8 key[16]; 237 size_t keylen; 238 } rc4; 239 struct { 240 u8 cbc[32]; 241 size_t block_size; 242 void *ctx_enc; 243 void *ctx_dec; 244 } aes; 245 struct { 246 struct des3_key_s key; 247 u8 cbc[8]; 248 } des3; 249 } u; 250 }; 251 252 253 struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg, 254 const u8 *iv, const u8 *key, 255 size_t key_len) 256 { 257 struct crypto_cipher *ctx; 258 259 ctx = os_zalloc(sizeof(*ctx)); 260 if (ctx == NULL) 261 return NULL; 262 263 ctx->alg = alg; 264 265 switch (alg) { 266 case CRYPTO_CIPHER_ALG_RC4: 267 if (key_len > sizeof(ctx->u.rc4.key)) { 268 os_free(ctx); 269 return NULL; 270 } 271 ctx->u.rc4.keylen = key_len; 272 os_memcpy(ctx->u.rc4.key, key, key_len); 273 break; 274 case CRYPTO_CIPHER_ALG_AES: 275 if (key_len > sizeof(ctx->u.aes.cbc)) { 276 os_free(ctx); 277 return NULL; 278 } 279 ctx->u.aes.ctx_enc = aes_encrypt_init(key, key_len); 280 if (ctx->u.aes.ctx_enc == NULL) { 281 os_free(ctx); 282 return NULL; 283 } 284 ctx->u.aes.ctx_dec = aes_decrypt_init(key, key_len); 285 if (ctx->u.aes.ctx_dec == NULL) { 286 aes_encrypt_deinit(ctx->u.aes.ctx_enc); 287 os_free(ctx); 288 return NULL; 289 } 290 ctx->u.aes.block_size = key_len; 291 os_memcpy(ctx->u.aes.cbc, iv, ctx->u.aes.block_size); 292 break; 293 case CRYPTO_CIPHER_ALG_3DES: 294 if (key_len != 24) { 295 os_free(ctx); 296 return NULL; 297 } 298 des3_key_setup(key, &ctx->u.des3.key); 299 os_memcpy(ctx->u.des3.cbc, iv, 8); 300 break; 301 default: 302 os_free(ctx); 303 return NULL; 304 } 305 306 return ctx; 307 } 308 309 310 int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain, 311 u8 *crypt, size_t len) 312 { 313 size_t i, j, blocks; 314 315 switch (ctx->alg) { 316 case CRYPTO_CIPHER_ALG_RC4: 317 if (plain != crypt) 318 os_memcpy(crypt, plain, len); 319 rc4_skip(ctx->u.rc4.key, ctx->u.rc4.keylen, 320 ctx->u.rc4.used_bytes, crypt, len); 321 ctx->u.rc4.used_bytes += len; 322 break; 323 case CRYPTO_CIPHER_ALG_AES: 324 if (len % ctx->u.aes.block_size) 325 return -1; 326 blocks = len / ctx->u.aes.block_size; 327 for (i = 0; i < blocks; i++) { 328 for (j = 0; j < ctx->u.aes.block_size; j++) 329 ctx->u.aes.cbc[j] ^= plain[j]; 330 aes_encrypt(ctx->u.aes.ctx_enc, ctx->u.aes.cbc, 331 ctx->u.aes.cbc); 332 os_memcpy(crypt, ctx->u.aes.cbc, 333 ctx->u.aes.block_size); 334 plain += ctx->u.aes.block_size; 335 crypt += ctx->u.aes.block_size; 336 } 337 break; 338 case CRYPTO_CIPHER_ALG_3DES: 339 if (len % 8) 340 return -1; 341 blocks = len / 8; 342 for (i = 0; i < blocks; i++) { 343 for (j = 0; j < 8; j++) 344 ctx->u.des3.cbc[j] ^= plain[j]; 345 des3_encrypt(ctx->u.des3.cbc, &ctx->u.des3.key, 346 ctx->u.des3.cbc); 347 os_memcpy(crypt, ctx->u.des3.cbc, 8); 348 plain += 8; 349 crypt += 8; 350 } 351 break; 352 default: 353 return -1; 354 } 355 356 return 0; 357 } 358 359 360 int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt, 361 u8 *plain, size_t len) 362 { 363 size_t i, j, blocks; 364 u8 tmp[32]; 365 366 switch (ctx->alg) { 367 case CRYPTO_CIPHER_ALG_RC4: 368 if (plain != crypt) 369 os_memcpy(plain, crypt, len); 370 rc4_skip(ctx->u.rc4.key, ctx->u.rc4.keylen, 371 ctx->u.rc4.used_bytes, plain, len); 372 ctx->u.rc4.used_bytes += len; 373 break; 374 case CRYPTO_CIPHER_ALG_AES: 375 if (len % ctx->u.aes.block_size) 376 return -1; 377 blocks = len / ctx->u.aes.block_size; 378 for (i = 0; i < blocks; i++) { 379 os_memcpy(tmp, crypt, ctx->u.aes.block_size); 380 aes_decrypt(ctx->u.aes.ctx_dec, crypt, plain); 381 for (j = 0; j < ctx->u.aes.block_size; j++) 382 plain[j] ^= ctx->u.aes.cbc[j]; 383 os_memcpy(ctx->u.aes.cbc, tmp, ctx->u.aes.block_size); 384 plain += ctx->u.aes.block_size; 385 crypt += ctx->u.aes.block_size; 386 } 387 break; 388 case CRYPTO_CIPHER_ALG_3DES: 389 if (len % 8) 390 return -1; 391 blocks = len / 8; 392 for (i = 0; i < blocks; i++) { 393 os_memcpy(tmp, crypt, 8); 394 des3_decrypt(crypt, &ctx->u.des3.key, plain); 395 for (j = 0; j < 8; j++) 396 plain[j] ^= ctx->u.des3.cbc[j]; 397 os_memcpy(ctx->u.des3.cbc, tmp, 8); 398 plain += 8; 399 crypt += 8; 400 } 401 break; 402 default: 403 return -1; 404 } 405 406 return 0; 407 } 408 409 410 void crypto_cipher_deinit(struct crypto_cipher *ctx) 411 { 412 switch (ctx->alg) { 413 case CRYPTO_CIPHER_ALG_AES: 414 aes_encrypt_deinit(ctx->u.aes.ctx_enc); 415 aes_decrypt_deinit(ctx->u.aes.ctx_dec); 416 break; 417 case CRYPTO_CIPHER_ALG_3DES: 418 break; 419 default: 420 break; 421 } 422 os_free(ctx); 423 } 424 425 426 /* Dummy structures; these are just typecast to struct crypto_rsa_key */ 427 struct crypto_public_key; 428 struct crypto_private_key; 429 430 431 struct crypto_public_key * crypto_public_key_import(const u8 *key, size_t len) 432 { 433 return (struct crypto_public_key *) 434 crypto_rsa_import_public_key(key, len); 435 } 436 437 438 #ifdef EAP_TLS_FUNCS 439 static struct crypto_private_key * 440 crypto_pkcs8_key_import(const u8 *buf, size_t len) 441 { 442 struct asn1_hdr hdr; 443 const u8 *pos, *end; 444 struct bignum *zero; 445 struct asn1_oid oid; 446 char obuf[80]; 447 448 /* PKCS #8, Chapter 6 */ 449 450 /* PrivateKeyInfo ::= SEQUENCE */ 451 if (asn1_get_next(buf, len, &hdr) < 0 || 452 hdr.class != ASN1_CLASS_UNIVERSAL || 453 hdr.tag != ASN1_TAG_SEQUENCE) { 454 wpa_printf(MSG_DEBUG, "PKCS #8: Does not start with PKCS #8 " 455 "header (SEQUENCE); assume PKCS #8 not used"); 456 return NULL; 457 } 458 pos = hdr.payload; 459 end = pos + hdr.length; 460 461 /* version Version (Version ::= INTEGER) */ 462 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 463 hdr.class != ASN1_CLASS_UNIVERSAL || hdr.tag != ASN1_TAG_INTEGER) { 464 wpa_printf(MSG_DEBUG, "PKCS #8: Expected INTEGER - found " 465 "class %d tag 0x%x; assume PKCS #8 not used", 466 hdr.class, hdr.tag); 467 return NULL; 468 } 469 470 zero = bignum_init(); 471 if (zero == NULL) 472 return NULL; 473 474 if (bignum_set_unsigned_bin(zero, hdr.payload, hdr.length) < 0) { 475 wpa_printf(MSG_DEBUG, "PKCS #8: Failed to parse INTEGER"); 476 bignum_deinit(zero); 477 return NULL; 478 } 479 pos = hdr.payload + hdr.length; 480 481 if (bignum_cmp_d(zero, 0) != 0) { 482 wpa_printf(MSG_DEBUG, "PKCS #8: Expected zero INTEGER in the " 483 "beginning of private key; not found; assume " 484 "PKCS #8 not used"); 485 bignum_deinit(zero); 486 return NULL; 487 } 488 bignum_deinit(zero); 489 490 /* privateKeyAlgorithm PrivateKeyAlgorithmIdentifier 491 * (PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier) */ 492 if (asn1_get_next(pos, len, &hdr) < 0 || 493 hdr.class != ASN1_CLASS_UNIVERSAL || 494 hdr.tag != ASN1_TAG_SEQUENCE) { 495 wpa_printf(MSG_DEBUG, "PKCS #8: Expected SEQUENCE " 496 "(AlgorithmIdentifier) - found class %d tag 0x%x; " 497 "assume PKCS #8 not used", 498 hdr.class, hdr.tag); 499 return NULL; 500 } 501 502 if (asn1_get_oid(hdr.payload, hdr.length, &oid, &pos)) { 503 wpa_printf(MSG_DEBUG, "PKCS #8: Failed to parse OID " 504 "(algorithm); assume PKCS #8 not used"); 505 return NULL; 506 } 507 508 asn1_oid_to_str(&oid, obuf, sizeof(obuf)); 509 wpa_printf(MSG_DEBUG, "PKCS #8: algorithm=%s", obuf); 510 511 if (oid.len != 7 || 512 oid.oid[0] != 1 /* iso */ || 513 oid.oid[1] != 2 /* member-body */ || 514 oid.oid[2] != 840 /* us */ || 515 oid.oid[3] != 113549 /* rsadsi */ || 516 oid.oid[4] != 1 /* pkcs */ || 517 oid.oid[5] != 1 /* pkcs-1 */ || 518 oid.oid[6] != 1 /* rsaEncryption */) { 519 wpa_printf(MSG_DEBUG, "PKCS #8: Unsupported private key " 520 "algorithm %s", obuf); 521 return NULL; 522 } 523 524 pos = hdr.payload + hdr.length; 525 526 /* privateKey PrivateKey (PrivateKey ::= OCTET STRING) */ 527 if (asn1_get_next(pos, end - pos, &hdr) < 0 || 528 hdr.class != ASN1_CLASS_UNIVERSAL || 529 hdr.tag != ASN1_TAG_OCTETSTRING) { 530 wpa_printf(MSG_DEBUG, "PKCS #8: Expected OCTETSTRING " 531 "(privateKey) - found class %d tag 0x%x", 532 hdr.class, hdr.tag); 533 return NULL; 534 } 535 wpa_printf(MSG_DEBUG, "PKCS #8: Try to parse RSAPrivateKey"); 536 537 return (struct crypto_private_key *) 538 crypto_rsa_import_private_key(hdr.payload, hdr.length); 539 } 540 #endif /* EAP_TLS_FUNCS */ 541 542 543 struct crypto_private_key * crypto_private_key_import(const u8 *key, 544 size_t len) 545 { 546 struct crypto_private_key *res; 547 548 /* First, check for possible PKCS #8 encoding */ 549 res = crypto_pkcs8_key_import(key, len); 550 if (res) 551 return res; 552 553 /* Not PKCS#8, so try to import PKCS #1 encoded RSA private key */ 554 wpa_printf(MSG_DEBUG, "Trying to parse PKCS #1 encoded RSA private " 555 "key"); 556 return (struct crypto_private_key *) 557 crypto_rsa_import_private_key(key, len); 558 } 559 560 561 struct crypto_public_key * crypto_public_key_from_cert(const u8 *buf, 562 size_t len) 563 { 564 /* No X.509 support in crypto_internal.c */ 565 return NULL; 566 } 567 568 569 static int pkcs1_generate_encryption_block(u8 block_type, size_t modlen, 570 const u8 *in, size_t inlen, 571 u8 *out, size_t *outlen) 572 { 573 size_t ps_len; 574 u8 *pos; 575 576 /* 577 * PKCS #1 v1.5, 8.1: 578 * 579 * EB = 00 || BT || PS || 00 || D 580 * BT = 00 or 01 for private-key operation; 02 for public-key operation 581 * PS = k-3-||D||; at least eight octets 582 * (BT=0: PS=0x00, BT=1: PS=0xff, BT=2: PS=pseudorandom non-zero) 583 * k = length of modulus in octets (modlen) 584 */ 585 586 if (modlen < 12 || modlen > *outlen || inlen > modlen - 11) { 587 wpa_printf(MSG_DEBUG, "PKCS #1: %s - Invalid buffer " 588 "lengths (modlen=%lu outlen=%lu inlen=%lu)", 589 __func__, (unsigned long) modlen, 590 (unsigned long) *outlen, 591 (unsigned long) inlen); 592 return -1; 593 } 594 595 pos = out; 596 *pos++ = 0x00; 597 *pos++ = block_type; /* BT */ 598 ps_len = modlen - inlen - 3; 599 switch (block_type) { 600 case 0: 601 os_memset(pos, 0x00, ps_len); 602 pos += ps_len; 603 break; 604 case 1: 605 os_memset(pos, 0xff, ps_len); 606 pos += ps_len; 607 break; 608 case 2: 609 if (os_get_random(pos, ps_len) < 0) { 610 wpa_printf(MSG_DEBUG, "PKCS #1: %s - Failed to get " 611 "random data for PS", __func__); 612 return -1; 613 } 614 while (ps_len--) { 615 if (*pos == 0x00) 616 *pos = 0x01; 617 pos++; 618 } 619 break; 620 default: 621 wpa_printf(MSG_DEBUG, "PKCS #1: %s - Unsupported block type " 622 "%d", __func__, block_type); 623 return -1; 624 } 625 *pos++ = 0x00; 626 os_memcpy(pos, in, inlen); /* D */ 627 628 return 0; 629 } 630 631 632 static int crypto_rsa_encrypt_pkcs1(int block_type, struct crypto_rsa_key *key, 633 int use_private, 634 const u8 *in, size_t inlen, 635 u8 *out, size_t *outlen) 636 { 637 size_t modlen; 638 639 modlen = crypto_rsa_get_modulus_len(key); 640 641 if (pkcs1_generate_encryption_block(block_type, modlen, in, inlen, 642 out, outlen) < 0) 643 return -1; 644 645 return crypto_rsa_exptmod(out, modlen, out, outlen, key, use_private); 646 } 647 648 649 int crypto_public_key_encrypt_pkcs1_v15(struct crypto_public_key *key, 650 const u8 *in, size_t inlen, 651 u8 *out, size_t *outlen) 652 { 653 return crypto_rsa_encrypt_pkcs1(2, (struct crypto_rsa_key *) key, 654 0, in, inlen, out, outlen); 655 } 656 657 658 int crypto_private_key_decrypt_pkcs1_v15(struct crypto_private_key *key, 659 const u8 *in, size_t inlen, 660 u8 *out, size_t *outlen) 661 { 662 struct crypto_rsa_key *rkey = (struct crypto_rsa_key *) key; 663 int res; 664 u8 *pos, *end; 665 666 res = crypto_rsa_exptmod(in, inlen, out, outlen, rkey, 1); 667 if (res) 668 return res; 669 670 if (*outlen < 2 || out[0] != 0 || out[1] != 2) 671 return -1; 672 673 /* Skip PS (pseudorandom non-zero octets) */ 674 pos = out + 2; 675 end = out + *outlen; 676 while (*pos && pos < end) 677 pos++; 678 if (pos == end) 679 return -1; 680 pos++; 681 682 *outlen -= pos - out; 683 684 /* Strip PKCS #1 header */ 685 os_memmove(out, pos, *outlen); 686 687 return 0; 688 } 689 690 691 int crypto_private_key_sign_pkcs1(struct crypto_private_key *key, 692 const u8 *in, size_t inlen, 693 u8 *out, size_t *outlen) 694 { 695 return crypto_rsa_encrypt_pkcs1(1, (struct crypto_rsa_key *) key, 696 1, in, inlen, out, outlen); 697 } 698 699 700 void crypto_public_key_free(struct crypto_public_key *key) 701 { 702 crypto_rsa_free((struct crypto_rsa_key *) key); 703 } 704 705 706 void crypto_private_key_free(struct crypto_private_key *key) 707 { 708 crypto_rsa_free((struct crypto_rsa_key *) key); 709 } 710 711 712 int crypto_public_key_decrypt_pkcs1(struct crypto_public_key *key, 713 const u8 *crypt, size_t crypt_len, 714 u8 *plain, size_t *plain_len) 715 { 716 size_t len; 717 u8 *pos; 718 719 len = *plain_len; 720 if (crypto_rsa_exptmod(crypt, crypt_len, plain, &len, 721 (struct crypto_rsa_key *) key, 0) < 0) 722 return -1; 723 724 /* 725 * PKCS #1 v1.5, 8.1: 726 * 727 * EB = 00 || BT || PS || 00 || D 728 * BT = 00 or 01 729 * PS = k-3-||D|| times (00 if BT=00) or (FF if BT=01) 730 * k = length of modulus in octets 731 */ 732 733 if (len < 3 + 8 + 16 /* min hash len */ || 734 plain[0] != 0x00 || (plain[1] != 0x00 && plain[1] != 0x01)) { 735 wpa_printf(MSG_INFO, "LibTomCrypt: Invalid signature EB " 736 "structure"); 737 return -1; 738 } 739 740 pos = plain + 3; 741 if (plain[1] == 0x00) { 742 /* BT = 00 */ 743 if (plain[2] != 0x00) { 744 wpa_printf(MSG_INFO, "LibTomCrypt: Invalid signature " 745 "PS (BT=00)"); 746 return -1; 747 } 748 while (pos + 1 < plain + len && *pos == 0x00 && pos[1] == 0x00) 749 pos++; 750 } else { 751 /* BT = 01 */ 752 if (plain[2] != 0xff) { 753 wpa_printf(MSG_INFO, "LibTomCrypt: Invalid signature " 754 "PS (BT=01)"); 755 return -1; 756 } 757 while (pos < plain + len && *pos == 0xff) 758 pos++; 759 } 760 761 if (pos - plain - 2 < 8) { 762 /* PKCS #1 v1.5, 8.1: At least eight octets long PS */ 763 wpa_printf(MSG_INFO, "LibTomCrypt: Too short signature " 764 "padding"); 765 return -1; 766 } 767 768 if (pos + 16 /* min hash len */ >= plain + len || *pos != 0x00) { 769 wpa_printf(MSG_INFO, "LibTomCrypt: Invalid signature EB " 770 "structure (2)"); 771 return -1; 772 } 773 pos++; 774 len -= pos - plain; 775 776 /* Strip PKCS #1 header */ 777 os_memmove(plain, pos, len); 778 *plain_len = len; 779 780 return 0; 781 } 782 783 784 int crypto_global_init(void) 785 { 786 return 0; 787 } 788 789 790 void crypto_global_deinit(void) 791 { 792 } 793 #endif /* CONFIG_TLS_INTERNAL */ 794 795 796 #if defined(EAP_FAST) || defined(CONFIG_WPS) 797 798 int crypto_mod_exp(const u8 *base, size_t base_len, 799 const u8 *power, size_t power_len, 800 const u8 *modulus, size_t modulus_len, 801 u8 *result, size_t *result_len) 802 { 803 struct bignum *bn_base, *bn_exp, *bn_modulus, *bn_result; 804 int ret = -1; 805 806 bn_base = bignum_init(); 807 bn_exp = bignum_init(); 808 bn_modulus = bignum_init(); 809 bn_result = bignum_init(); 810 811 if (bn_base == NULL || bn_exp == NULL || bn_modulus == NULL || 812 bn_result == NULL) 813 goto error; 814 815 if (bignum_set_unsigned_bin(bn_base, base, base_len) < 0 || 816 bignum_set_unsigned_bin(bn_exp, power, power_len) < 0 || 817 bignum_set_unsigned_bin(bn_modulus, modulus, modulus_len) < 0) 818 goto error; 819 820 if (bignum_exptmod(bn_base, bn_exp, bn_modulus, bn_result) < 0) 821 goto error; 822 823 ret = bignum_get_unsigned_bin(bn_result, result, result_len); 824 825 error: 826 bignum_deinit(bn_base); 827 bignum_deinit(bn_exp); 828 bignum_deinit(bn_modulus); 829 bignum_deinit(bn_result); 830 return ret; 831 } 832 833 #endif /* EAP_FAST || CONFIG_WPS */ 834 835 836 #endif /* CONFIG_CRYPTO_INTERNAL */ 837