00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "includes.h"
00016
00017 #include "common.h"
00018 #include "crypto.h"
00019 #include "sha1_i.h"
00020 #include "md5_i.h"
00021
00022 struct crypto_hash {
00023 enum crypto_hash_alg alg;
00024 union {
00025 struct MD5Context md5;
00026 struct SHA1Context sha1;
00027 } u;
00028 u8 key[64];
00029 size_t key_len;
00030 };
00031
00032
00033 struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key,
00034 size_t key_len)
00035 {
00036 struct crypto_hash *ctx;
00037 u8 k_pad[64];
00038 u8 tk[20];
00039 size_t i;
00040
00041 ctx = os_zalloc(sizeof(*ctx));
00042 if (ctx == NULL)
00043 return NULL;
00044
00045 ctx->alg = alg;
00046
00047 switch (alg) {
00048 case CRYPTO_HASH_ALG_MD5:
00049 MD5Init(&ctx->u.md5);
00050 break;
00051 case CRYPTO_HASH_ALG_SHA1:
00052 SHA1Init(&ctx->u.sha1);
00053 break;
00054 case CRYPTO_HASH_ALG_HMAC_MD5:
00055 if (key_len > sizeof(k_pad)) {
00056 MD5Init(&ctx->u.md5);
00057 MD5Update(&ctx->u.md5, key, key_len);
00058 MD5Final(tk, &ctx->u.md5);
00059 key = tk;
00060 key_len = 16;
00061 }
00062 os_memcpy(ctx->key, key, key_len);
00063 ctx->key_len = key_len;
00064
00065 os_memcpy(k_pad, key, key_len);
00066 os_memset(k_pad + key_len, 0, sizeof(k_pad) - key_len);
00067 for (i = 0; i < sizeof(k_pad); i++)
00068 k_pad[i] ^= 0x36;
00069 MD5Init(&ctx->u.md5);
00070 MD5Update(&ctx->u.md5, k_pad, sizeof(k_pad));
00071 break;
00072 case CRYPTO_HASH_ALG_HMAC_SHA1:
00073 if (key_len > sizeof(k_pad)) {
00074 SHA1Init(&ctx->u.sha1);
00075 SHA1Update(&ctx->u.sha1, key, key_len);
00076 SHA1Final(tk, &ctx->u.sha1);
00077 key = tk;
00078 key_len = 20;
00079 }
00080 os_memcpy(ctx->key, key, key_len);
00081 ctx->key_len = key_len;
00082
00083 os_memcpy(k_pad, key, key_len);
00084 os_memset(k_pad + key_len, 0, sizeof(k_pad) - key_len);
00085 for (i = 0; i < sizeof(k_pad); i++)
00086 k_pad[i] ^= 0x36;
00087 SHA1Init(&ctx->u.sha1);
00088 SHA1Update(&ctx->u.sha1, k_pad, sizeof(k_pad));
00089 break;
00090 default:
00091 os_free(ctx);
00092 return NULL;
00093 }
00094
00095 return ctx;
00096 }
00097
00098
00099 void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len)
00100 {
00101 if (ctx == NULL)
00102 return;
00103
00104 switch (ctx->alg) {
00105 case CRYPTO_HASH_ALG_MD5:
00106 case CRYPTO_HASH_ALG_HMAC_MD5:
00107 MD5Update(&ctx->u.md5, data, len);
00108 break;
00109 case CRYPTO_HASH_ALG_SHA1:
00110 case CRYPTO_HASH_ALG_HMAC_SHA1:
00111 SHA1Update(&ctx->u.sha1, data, len);
00112 break;
00113 }
00114 }
00115
00116
00117 int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len)
00118 {
00119 u8 k_pad[64];
00120 size_t i;
00121
00122 if (ctx == NULL)
00123 return -2;
00124
00125 if (mac == NULL || len == NULL) {
00126 os_free(ctx);
00127 return 0;
00128 }
00129
00130 switch (ctx->alg) {
00131 case CRYPTO_HASH_ALG_MD5:
00132 if (*len < 16) {
00133 *len = 16;
00134 os_free(ctx);
00135 return -1;
00136 }
00137 *len = 16;
00138 MD5Final(mac, &ctx->u.md5);
00139 break;
00140 case CRYPTO_HASH_ALG_SHA1:
00141 if (*len < 20) {
00142 *len = 20;
00143 os_free(ctx);
00144 return -1;
00145 }
00146 *len = 20;
00147 SHA1Final(mac, &ctx->u.sha1);
00148 break;
00149 case CRYPTO_HASH_ALG_HMAC_MD5:
00150 if (*len < 16) {
00151 *len = 16;
00152 os_free(ctx);
00153 return -1;
00154 }
00155 *len = 16;
00156
00157 MD5Final(mac, &ctx->u.md5);
00158
00159 os_memcpy(k_pad, ctx->key, ctx->key_len);
00160 os_memset(k_pad + ctx->key_len, 0,
00161 sizeof(k_pad) - ctx->key_len);
00162 for (i = 0; i < sizeof(k_pad); i++)
00163 k_pad[i] ^= 0x5c;
00164 MD5Init(&ctx->u.md5);
00165 MD5Update(&ctx->u.md5, k_pad, sizeof(k_pad));
00166 MD5Update(&ctx->u.md5, mac, 16);
00167 MD5Final(mac, &ctx->u.md5);
00168 break;
00169 case CRYPTO_HASH_ALG_HMAC_SHA1:
00170 if (*len < 20) {
00171 *len = 20;
00172 os_free(ctx);
00173 return -1;
00174 }
00175 *len = 20;
00176
00177 SHA1Final(mac, &ctx->u.sha1);
00178
00179 os_memcpy(k_pad, ctx->key, ctx->key_len);
00180 os_memset(k_pad + ctx->key_len, 0,
00181 sizeof(k_pad) - ctx->key_len);
00182 for (i = 0; i < sizeof(k_pad); i++)
00183 k_pad[i] ^= 0x5c;
00184 SHA1Init(&ctx->u.sha1);
00185 SHA1Update(&ctx->u.sha1, k_pad, sizeof(k_pad));
00186 SHA1Update(&ctx->u.sha1, mac, 20);
00187 SHA1Final(mac, &ctx->u.sha1);
00188 break;
00189 }
00190
00191 os_free(ctx);
00192
00193 return 0;
00194 }
00195
00196
00197 int crypto_global_init(void)
00198 {
00199 return 0;
00200 }
00201
00202
00203 void crypto_global_deinit(void)
00204 {
00205 }