crypto_internal.c

Go to the documentation of this file.
00001 
00016 #include "includes.h"
00017 
00018 #include "common.h"
00019 #include "crypto.h"
00020 #include "md5.h"
00021 #include "sha1.h"
00022 #include "aes.h"
00023 #include "tls/rsa.h"
00024 #include "tls/bignum.h"
00025 #include "tls/pkcs1.h"
00026 #include "tls/pkcs8.h"
00027 #include "sha1_i.h"
00028 #include "md5_i.h"
00029 #include "des_i.h"
00030 
00031 #ifdef CONFIG_TLS_INTERNAL
00032 
00033 struct crypto_hash {
00034         enum crypto_hash_alg alg;
00035         union {
00036                 struct MD5Context md5;
00037                 struct SHA1Context sha1;
00038         } u;
00039         u8 key[64];
00040         size_t key_len;
00041 };
00042 
00043 
00044 struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key,
00045                                       size_t key_len)
00046 {
00047         struct crypto_hash *ctx;
00048         u8 k_pad[64];
00049         u8 tk[20];
00050         size_t i;
00051 
00052         ctx = os_zalloc(sizeof(*ctx));
00053         if (ctx == NULL)
00054                 return NULL;
00055 
00056         ctx->alg = alg;
00057 
00058         switch (alg) {
00059         case CRYPTO_HASH_ALG_MD5:
00060                 MD5Init(&ctx->u.md5);
00061                 break;
00062         case CRYPTO_HASH_ALG_SHA1:
00063                 SHA1Init(&ctx->u.sha1);
00064                 break;
00065         case CRYPTO_HASH_ALG_HMAC_MD5:
00066                 if (key_len > sizeof(k_pad)) {
00067                         MD5Init(&ctx->u.md5);
00068                         MD5Update(&ctx->u.md5, key, key_len);
00069                         MD5Final(tk, &ctx->u.md5);
00070                         key = tk;
00071                         key_len = 16;
00072                 }
00073                 os_memcpy(ctx->key, key, key_len);
00074                 ctx->key_len = key_len;
00075 
00076                 os_memcpy(k_pad, key, key_len);
00077                 os_memset(k_pad + key_len, 0, sizeof(k_pad) - key_len);
00078                 for (i = 0; i < sizeof(k_pad); i++)
00079                         k_pad[i] ^= 0x36;
00080                 MD5Init(&ctx->u.md5);
00081                 MD5Update(&ctx->u.md5, k_pad, sizeof(k_pad));
00082                 break;
00083         case CRYPTO_HASH_ALG_HMAC_SHA1:
00084                 if (key_len > sizeof(k_pad)) {
00085                         SHA1Init(&ctx->u.sha1);
00086                         SHA1Update(&ctx->u.sha1, key, key_len);
00087                         SHA1Final(tk, &ctx->u.sha1);
00088                         key = tk;
00089                         key_len = 20;
00090                 }
00091                 os_memcpy(ctx->key, key, key_len);
00092                 ctx->key_len = key_len;
00093 
00094                 os_memcpy(k_pad, key, key_len);
00095                 os_memset(k_pad + key_len, 0, sizeof(k_pad) - key_len);
00096                 for (i = 0; i < sizeof(k_pad); i++)
00097                         k_pad[i] ^= 0x36;
00098                 SHA1Init(&ctx->u.sha1);
00099                 SHA1Update(&ctx->u.sha1, k_pad, sizeof(k_pad));
00100                 break;
00101         default:
00102                 os_free(ctx);
00103                 return NULL;
00104         }
00105 
00106         return ctx;
00107 }
00108 
00109 
00110 void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len)
00111 {
00112         if (ctx == NULL)
00113                 return;
00114 
00115         switch (ctx->alg) {
00116         case CRYPTO_HASH_ALG_MD5:
00117         case CRYPTO_HASH_ALG_HMAC_MD5:
00118                 MD5Update(&ctx->u.md5, data, len);
00119                 break;
00120         case CRYPTO_HASH_ALG_SHA1:
00121         case CRYPTO_HASH_ALG_HMAC_SHA1:
00122                 SHA1Update(&ctx->u.sha1, data, len);
00123                 break;
00124         }
00125 }
00126 
00127 
00128 int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len)
00129 {
00130         u8 k_pad[64];
00131         size_t i;
00132 
00133         if (ctx == NULL)
00134                 return -2;
00135 
00136         if (mac == NULL || len == NULL) {
00137                 os_free(ctx);
00138                 return 0;
00139         }
00140 
00141         switch (ctx->alg) {
00142         case CRYPTO_HASH_ALG_MD5:
00143                 if (*len < 16) {
00144                         *len = 16;
00145                         os_free(ctx);
00146                         return -1;
00147                 }
00148                 *len = 16;
00149                 MD5Final(mac, &ctx->u.md5);
00150                 break;
00151         case CRYPTO_HASH_ALG_SHA1:
00152                 if (*len < 20) {
00153                         *len = 20;
00154                         os_free(ctx);
00155                         return -1;
00156                 }
00157                 *len = 20;
00158                 SHA1Final(mac, &ctx->u.sha1);
00159                 break;
00160         case CRYPTO_HASH_ALG_HMAC_MD5:
00161                 if (*len < 16) {
00162                         *len = 16;
00163                         os_free(ctx);
00164                         return -1;
00165                 }
00166                 *len = 16;
00167 
00168                 MD5Final(mac, &ctx->u.md5);
00169 
00170                 os_memcpy(k_pad, ctx->key, ctx->key_len);
00171                 os_memset(k_pad + ctx->key_len, 0,
00172                           sizeof(k_pad) - ctx->key_len);
00173                 for (i = 0; i < sizeof(k_pad); i++)
00174                         k_pad[i] ^= 0x5c;
00175                 MD5Init(&ctx->u.md5);
00176                 MD5Update(&ctx->u.md5, k_pad, sizeof(k_pad));
00177                 MD5Update(&ctx->u.md5, mac, 16);
00178                 MD5Final(mac, &ctx->u.md5);
00179                 break;
00180         case CRYPTO_HASH_ALG_HMAC_SHA1:
00181                 if (*len < 20) {
00182                         *len = 20;
00183                         os_free(ctx);
00184                         return -1;
00185                 }
00186                 *len = 20;
00187 
00188                 SHA1Final(mac, &ctx->u.sha1);
00189 
00190                 os_memcpy(k_pad, ctx->key, ctx->key_len);
00191                 os_memset(k_pad + ctx->key_len, 0,
00192                           sizeof(k_pad) - ctx->key_len);
00193                 for (i = 0; i < sizeof(k_pad); i++)
00194                         k_pad[i] ^= 0x5c;
00195                 SHA1Init(&ctx->u.sha1);
00196                 SHA1Update(&ctx->u.sha1, k_pad, sizeof(k_pad));
00197                 SHA1Update(&ctx->u.sha1, mac, 20);
00198                 SHA1Final(mac, &ctx->u.sha1);
00199                 break;
00200         }
00201 
00202         os_free(ctx);
00203 
00204         return 0;
00205 }
00206 
00207 
00208 struct crypto_cipher {
00209         enum crypto_cipher_alg alg;
00210         union {
00211                 struct {
00212                         size_t used_bytes;
00213                         u8 key[16];
00214                         size_t keylen;
00215                 } rc4;
00216                 struct {
00217                         u8 cbc[32];
00218                         size_t block_size;
00219                         void *ctx_enc;
00220                         void *ctx_dec;
00221                 } aes;
00222                 struct {
00223                         struct des3_key_s key;
00224                         u8 cbc[8];
00225                 } des3;
00226                 struct {
00227                         u32 ek[32];
00228                         u32 dk[32];
00229                         u8 cbc[8];
00230                 } des;
00231         } u;
00232 };
00233 
00234 
00235 struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg,
00236                                           const u8 *iv, const u8 *key,
00237                                           size_t key_len)
00238 {
00239         struct crypto_cipher *ctx;
00240 
00241         ctx = os_zalloc(sizeof(*ctx));
00242         if (ctx == NULL)
00243                 return NULL;
00244 
00245         ctx->alg = alg;
00246 
00247         switch (alg) {
00248         case CRYPTO_CIPHER_ALG_RC4:
00249                 if (key_len > sizeof(ctx->u.rc4.key)) {
00250                         os_free(ctx);
00251                         return NULL;
00252                 }
00253                 ctx->u.rc4.keylen = key_len;
00254                 os_memcpy(ctx->u.rc4.key, key, key_len);
00255                 break;
00256         case CRYPTO_CIPHER_ALG_AES:
00257                 if (key_len > sizeof(ctx->u.aes.cbc)) {
00258                         os_free(ctx);
00259                         return NULL;
00260                 }
00261                 ctx->u.aes.ctx_enc = aes_encrypt_init(key, key_len);
00262                 if (ctx->u.aes.ctx_enc == NULL) {
00263                         os_free(ctx);
00264                         return NULL;
00265                 }
00266                 ctx->u.aes.ctx_dec = aes_decrypt_init(key, key_len);
00267                 if (ctx->u.aes.ctx_dec == NULL) {
00268                         aes_encrypt_deinit(ctx->u.aes.ctx_enc);
00269                         os_free(ctx);
00270                         return NULL;
00271                 }
00272                 ctx->u.aes.block_size = key_len;
00273                 os_memcpy(ctx->u.aes.cbc, iv, ctx->u.aes.block_size);
00274                 break;
00275         case CRYPTO_CIPHER_ALG_3DES:
00276                 if (key_len != 24) {
00277                         os_free(ctx);
00278                         return NULL;
00279                 }
00280                 des3_key_setup(key, &ctx->u.des3.key);
00281                 os_memcpy(ctx->u.des3.cbc, iv, 8);
00282                 break;
00283         case CRYPTO_CIPHER_ALG_DES:
00284                 if (key_len != 8) {
00285                         os_free(ctx);
00286                         return NULL;
00287                 }
00288                 des_key_setup(key, ctx->u.des.ek, ctx->u.des.dk);
00289                 os_memcpy(ctx->u.des.cbc, iv, 8);
00290                 break;
00291         default:
00292                 os_free(ctx);
00293                 return NULL;
00294         }
00295 
00296         return ctx;
00297 }
00298 
00299 
00300 int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain,
00301                           u8 *crypt, size_t len)
00302 {
00303         size_t i, j, blocks;
00304 
00305         switch (ctx->alg) {
00306         case CRYPTO_CIPHER_ALG_RC4:
00307                 if (plain != crypt)
00308                         os_memcpy(crypt, plain, len);
00309                 rc4_skip(ctx->u.rc4.key, ctx->u.rc4.keylen,
00310                          ctx->u.rc4.used_bytes, crypt, len);
00311                 ctx->u.rc4.used_bytes += len;
00312                 break;
00313         case CRYPTO_CIPHER_ALG_AES:
00314                 if (len % ctx->u.aes.block_size)
00315                         return -1;
00316                 blocks = len / ctx->u.aes.block_size;
00317                 for (i = 0; i < blocks; i++) {
00318                         for (j = 0; j < ctx->u.aes.block_size; j++)
00319                                 ctx->u.aes.cbc[j] ^= plain[j];
00320                         aes_encrypt(ctx->u.aes.ctx_enc, ctx->u.aes.cbc,
00321                                     ctx->u.aes.cbc);
00322                         os_memcpy(crypt, ctx->u.aes.cbc,
00323                                   ctx->u.aes.block_size);
00324                         plain += ctx->u.aes.block_size;
00325                         crypt += ctx->u.aes.block_size;
00326                 }
00327                 break;
00328         case CRYPTO_CIPHER_ALG_3DES:
00329                 if (len % 8)
00330                         return -1;
00331                 blocks = len / 8;
00332                 for (i = 0; i < blocks; i++) {
00333                         for (j = 0; j < 8; j++)
00334                                 ctx->u.des3.cbc[j] ^= plain[j];
00335                         des3_encrypt(ctx->u.des3.cbc, &ctx->u.des3.key,
00336                                      ctx->u.des3.cbc);
00337                         os_memcpy(crypt, ctx->u.des3.cbc, 8);
00338                         plain += 8;
00339                         crypt += 8;
00340                 }
00341                 break;
00342         case CRYPTO_CIPHER_ALG_DES:
00343                 if (len % 8)
00344                         return -1;
00345                 blocks = len / 8;
00346                 for (i = 0; i < blocks; i++) {
00347                         for (j = 0; j < 8; j++)
00348                                 ctx->u.des3.cbc[j] ^= plain[j];
00349                         des_block_encrypt(ctx->u.des.cbc, ctx->u.des.ek,
00350                                           ctx->u.des.cbc);
00351                         os_memcpy(crypt, ctx->u.des.cbc, 8);
00352                         plain += 8;
00353                         crypt += 8;
00354                 }
00355                 break;
00356         default:
00357                 return -1;
00358         }
00359 
00360         return 0;
00361 }
00362 
00363 
00364 int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt,
00365                           u8 *plain, size_t len)
00366 {
00367         size_t i, j, blocks;
00368         u8 tmp[32];
00369 
00370         switch (ctx->alg) {
00371         case CRYPTO_CIPHER_ALG_RC4:
00372                 if (plain != crypt)
00373                         os_memcpy(plain, crypt, len);
00374                 rc4_skip(ctx->u.rc4.key, ctx->u.rc4.keylen,
00375                          ctx->u.rc4.used_bytes, plain, len);
00376                 ctx->u.rc4.used_bytes += len;
00377                 break;
00378         case CRYPTO_CIPHER_ALG_AES:
00379                 if (len % ctx->u.aes.block_size)
00380                         return -1;
00381                 blocks = len / ctx->u.aes.block_size;
00382                 for (i = 0; i < blocks; i++) {
00383                         os_memcpy(tmp, crypt, ctx->u.aes.block_size);
00384                         aes_decrypt(ctx->u.aes.ctx_dec, crypt, plain);
00385                         for (j = 0; j < ctx->u.aes.block_size; j++)
00386                                 plain[j] ^= ctx->u.aes.cbc[j];
00387                         os_memcpy(ctx->u.aes.cbc, tmp, ctx->u.aes.block_size);
00388                         plain += ctx->u.aes.block_size;
00389                         crypt += ctx->u.aes.block_size;
00390                 }
00391                 break;
00392         case CRYPTO_CIPHER_ALG_3DES:
00393                 if (len % 8)
00394                         return -1;
00395                 blocks = len / 8;
00396                 for (i = 0; i < blocks; i++) {
00397                         os_memcpy(tmp, crypt, 8);
00398                         des3_decrypt(crypt, &ctx->u.des3.key, plain);
00399                         for (j = 0; j < 8; j++)
00400                                 plain[j] ^= ctx->u.des3.cbc[j];
00401                         os_memcpy(ctx->u.des3.cbc, tmp, 8);
00402                         plain += 8;
00403                         crypt += 8;
00404                 }
00405                 break;
00406         case CRYPTO_CIPHER_ALG_DES:
00407                 if (len % 8)
00408                         return -1;
00409                 blocks = len / 8;
00410                 for (i = 0; i < blocks; i++) {
00411                         os_memcpy(tmp, crypt, 8);
00412                         des_block_decrypt(crypt, ctx->u.des.dk, plain);
00413                         for (j = 0; j < 8; j++)
00414                                 plain[j] ^= ctx->u.des.cbc[j];
00415                         os_memcpy(ctx->u.des.cbc, tmp, 8);
00416                         plain += 8;
00417                         crypt += 8;
00418                 }
00419                 break;
00420         default:
00421                 return -1;
00422         }
00423 
00424         return 0;
00425 }
00426 
00427 
00428 void crypto_cipher_deinit(struct crypto_cipher *ctx)
00429 {
00430         switch (ctx->alg) {
00431         case CRYPTO_CIPHER_ALG_AES:
00432                 aes_encrypt_deinit(ctx->u.aes.ctx_enc);
00433                 aes_decrypt_deinit(ctx->u.aes.ctx_dec);
00434                 break;
00435         case CRYPTO_CIPHER_ALG_3DES:
00436                 break;
00437         default:
00438                 break;
00439         }
00440         os_free(ctx);
00441 }
00442 
00443 
00444 /* Dummy structures; these are just typecast to struct crypto_rsa_key */
00445 struct crypto_public_key;
00446 struct crypto_private_key;
00447 
00448 
00449 struct crypto_public_key * crypto_public_key_import(const u8 *key, size_t len)
00450 {
00451         return (struct crypto_public_key *)
00452                 crypto_rsa_import_public_key(key, len);
00453 }
00454 
00455 
00456 struct crypto_private_key * crypto_private_key_import(const u8 *key,
00457                                                       size_t len,
00458                                                       const char *passwd)
00459 {
00460         struct crypto_private_key *res;
00461 
00462         /* First, check for possible PKCS #8 encoding */
00463         res = pkcs8_key_import(key, len);
00464         if (res)
00465                 return res;
00466 
00467         if (passwd) {
00468                 /* Try to parse as encrypted PKCS #8 */
00469                 res = pkcs8_enc_key_import(key, len, passwd);
00470                 if (res)
00471                         return res;
00472         }
00473 
00474         /* Not PKCS#8, so try to import PKCS #1 encoded RSA private key */
00475         wpa_printf(MSG_DEBUG, "Trying to parse PKCS #1 encoded RSA private "
00476                    "key");
00477         return (struct crypto_private_key *)
00478                 crypto_rsa_import_private_key(key, len);
00479 }
00480 
00481 
00482 struct crypto_public_key * crypto_public_key_from_cert(const u8 *buf,
00483                                                        size_t len)
00484 {
00485         /* No X.509 support in crypto_internal.c */
00486         return NULL;
00487 }
00488 
00489 
00490 int crypto_public_key_encrypt_pkcs1_v15(struct crypto_public_key *key,
00491                                         const u8 *in, size_t inlen,
00492                                         u8 *out, size_t *outlen)
00493 {
00494         return pkcs1_encrypt(2, (struct crypto_rsa_key *) key,
00495                              0, in, inlen, out, outlen);
00496 }
00497 
00498 
00499 int crypto_private_key_decrypt_pkcs1_v15(struct crypto_private_key *key,
00500                                          const u8 *in, size_t inlen,
00501                                          u8 *out, size_t *outlen)
00502 {
00503         return pkcs1_v15_private_key_decrypt((struct crypto_rsa_key *) key,
00504                                              in, inlen, out, outlen);
00505 }
00506 
00507 
00508 int crypto_private_key_sign_pkcs1(struct crypto_private_key *key,
00509                                   const u8 *in, size_t inlen,
00510                                   u8 *out, size_t *outlen)
00511 {
00512         return pkcs1_encrypt(1, (struct crypto_rsa_key *) key,
00513                              1, in, inlen, out, outlen);
00514 }
00515 
00516 
00517 void crypto_public_key_free(struct crypto_public_key *key)
00518 {
00519         crypto_rsa_free((struct crypto_rsa_key *) key);
00520 }
00521 
00522 
00523 void crypto_private_key_free(struct crypto_private_key *key)
00524 {
00525         crypto_rsa_free((struct crypto_rsa_key *) key);
00526 }
00527 
00528 
00529 int crypto_public_key_decrypt_pkcs1(struct crypto_public_key *key,
00530                                     const u8 *crypt, size_t crypt_len,
00531                                     u8 *plain, size_t *plain_len)
00532 {
00533         return pkcs1_decrypt_public_key((struct crypto_rsa_key *) key,
00534                                         crypt, crypt_len, plain, plain_len);
00535 }
00536 
00537 
00538 int crypto_global_init(void)
00539 {
00540         return 0;
00541 }
00542 
00543 
00544 void crypto_global_deinit(void)
00545 {
00546 }
00547 #endif /* CONFIG_TLS_INTERNAL */
00548 
00549 
00550 #ifdef CONFIG_MODEXP
00551 
00552 int crypto_mod_exp(const u8 *base, size_t base_len,
00553                    const u8 *power, size_t power_len,
00554                    const u8 *modulus, size_t modulus_len,
00555                    u8 *result, size_t *result_len)
00556 {
00557         struct bignum *bn_base, *bn_exp, *bn_modulus, *bn_result;
00558         int ret = -1;
00559 
00560         bn_base = bignum_init();
00561         bn_exp = bignum_init();
00562         bn_modulus = bignum_init();
00563         bn_result = bignum_init();
00564 
00565         if (bn_base == NULL || bn_exp == NULL || bn_modulus == NULL ||
00566             bn_result == NULL)
00567                 goto error;
00568 
00569         if (bignum_set_unsigned_bin(bn_base, base, base_len) < 0 ||
00570             bignum_set_unsigned_bin(bn_exp, power, power_len) < 0 ||
00571             bignum_set_unsigned_bin(bn_modulus, modulus, modulus_len) < 0)
00572                 goto error;
00573 
00574         if (bignum_exptmod(bn_base, bn_exp, bn_modulus, bn_result) < 0)
00575                 goto error;
00576 
00577         ret = bignum_get_unsigned_bin(bn_result, result, result_len);
00578 
00579 error:
00580         bignum_deinit(bn_base);
00581         bignum_deinit(bn_exp);
00582         bignum_deinit(bn_modulus);
00583         bignum_deinit(bn_result);
00584         return ret;
00585 }
00586 
00587 #endif /* CONFIG_MODEXP */
00588 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines

Generated on Sat Nov 21 23:16:50 2009 for hostapd by  doxygen 1.6.1