1 /* 2 * Crypto wrapper for internal crypto implementation 3 * Copyright (c) 2006-2011, 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 9 #include "includes.h" 10 11 #include "common.h" 12 #include "crypto.h" 13 #include "sha256_i.h" 14 #include "sha384_i.h" 15 #include "sha512_i.h" 16 #include "sha1_i.h" 17 #include "md5_i.h" 18 19 struct crypto_hash { 20 enum crypto_hash_alg alg; 21 union { 22 struct MD5Context md5; 23 struct SHA1Context sha1; 24 #ifdef CONFIG_SHA256 25 struct sha256_state sha256; 26 #endif /* CONFIG_SHA256 */ 27 #ifdef CONFIG_INTERNAL_SHA384 28 struct sha384_state sha384; 29 #endif /* CONFIG_INTERNAL_SHA384 */ 30 #ifdef CONFIG_INTERNAL_SHA512 31 struct sha512_state sha512; 32 #endif /* CONFIG_INTERNAL_SHA512 */ 33 } u; 34 u8 key[64]; 35 size_t key_len; 36 }; 37 38 39 struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key, 40 size_t key_len) 41 { 42 struct crypto_hash *ctx; 43 u8 k_pad[64]; 44 u8 tk[32]; 45 size_t i; 46 47 ctx = os_zalloc(sizeof(*ctx)); 48 if (ctx == NULL) 49 return NULL; 50 51 ctx->alg = alg; 52 53 switch (alg) { 54 case CRYPTO_HASH_ALG_MD5: 55 MD5Init(&ctx->u.md5); 56 break; 57 case CRYPTO_HASH_ALG_SHA1: 58 SHA1Init(&ctx->u.sha1); 59 break; 60 #ifdef CONFIG_SHA256 61 case CRYPTO_HASH_ALG_SHA256: 62 sha256_init(&ctx->u.sha256); 63 break; 64 #endif /* CONFIG_SHA256 */ 65 #ifdef CONFIG_INTERNAL_SHA384 66 case CRYPTO_HASH_ALG_SHA384: 67 sha384_init(&ctx->u.sha384); 68 break; 69 #endif /* CONFIG_INTERNAL_SHA384 */ 70 #ifdef CONFIG_INTERNAL_SHA512 71 case CRYPTO_HASH_ALG_SHA512: 72 sha512_init(&ctx->u.sha512); 73 break; 74 #endif /* CONFIG_INTERNAL_SHA512 */ 75 case CRYPTO_HASH_ALG_HMAC_MD5: 76 if (key_len > sizeof(k_pad)) { 77 MD5Init(&ctx->u.md5); 78 MD5Update(&ctx->u.md5, key, key_len); 79 MD5Final(tk, &ctx->u.md5); 80 key = tk; 81 key_len = 16; 82 } 83 os_memcpy(ctx->key, key, key_len); 84 ctx->key_len = key_len; 85 86 os_memcpy(k_pad, key, key_len); 87 if (key_len < sizeof(k_pad)) 88 os_memset(k_pad + key_len, 0, sizeof(k_pad) - key_len); 89 for (i = 0; i < sizeof(k_pad); i++) 90 k_pad[i] ^= 0x36; 91 MD5Init(&ctx->u.md5); 92 MD5Update(&ctx->u.md5, k_pad, sizeof(k_pad)); 93 break; 94 case CRYPTO_HASH_ALG_HMAC_SHA1: 95 if (key_len > sizeof(k_pad)) { 96 SHA1Init(&ctx->u.sha1); 97 SHA1Update(&ctx->u.sha1, key, key_len); 98 SHA1Final(tk, &ctx->u.sha1); 99 key = tk; 100 key_len = 20; 101 } 102 os_memcpy(ctx->key, key, key_len); 103 ctx->key_len = key_len; 104 105 os_memcpy(k_pad, key, key_len); 106 if (key_len < sizeof(k_pad)) 107 os_memset(k_pad + key_len, 0, sizeof(k_pad) - key_len); 108 for (i = 0; i < sizeof(k_pad); i++) 109 k_pad[i] ^= 0x36; 110 SHA1Init(&ctx->u.sha1); 111 SHA1Update(&ctx->u.sha1, k_pad, sizeof(k_pad)); 112 break; 113 #ifdef CONFIG_SHA256 114 case CRYPTO_HASH_ALG_HMAC_SHA256: 115 if (key_len > sizeof(k_pad)) { 116 sha256_init(&ctx->u.sha256); 117 sha256_process(&ctx->u.sha256, key, key_len); 118 sha256_done(&ctx->u.sha256, tk); 119 key = tk; 120 key_len = 32; 121 } 122 os_memcpy(ctx->key, key, key_len); 123 ctx->key_len = key_len; 124 125 os_memcpy(k_pad, key, key_len); 126 if (key_len < sizeof(k_pad)) 127 os_memset(k_pad + key_len, 0, sizeof(k_pad) - key_len); 128 for (i = 0; i < sizeof(k_pad); i++) 129 k_pad[i] ^= 0x36; 130 sha256_init(&ctx->u.sha256); 131 sha256_process(&ctx->u.sha256, k_pad, sizeof(k_pad)); 132 break; 133 #endif /* CONFIG_SHA256 */ 134 default: 135 os_free(ctx); 136 return NULL; 137 } 138 139 return ctx; 140 } 141 142 143 void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len) 144 { 145 if (ctx == NULL) 146 return; 147 148 switch (ctx->alg) { 149 case CRYPTO_HASH_ALG_MD5: 150 case CRYPTO_HASH_ALG_HMAC_MD5: 151 MD5Update(&ctx->u.md5, data, len); 152 break; 153 case CRYPTO_HASH_ALG_SHA1: 154 case CRYPTO_HASH_ALG_HMAC_SHA1: 155 SHA1Update(&ctx->u.sha1, data, len); 156 break; 157 #ifdef CONFIG_SHA256 158 case CRYPTO_HASH_ALG_SHA256: 159 case CRYPTO_HASH_ALG_HMAC_SHA256: 160 sha256_process(&ctx->u.sha256, data, len); 161 break; 162 #endif /* CONFIG_SHA256 */ 163 #ifdef CONFIG_INTERNAL_SHA384 164 case CRYPTO_HASH_ALG_SHA384: 165 sha384_process(&ctx->u.sha384, data, len); 166 break; 167 #endif /* CONFIG_INTERNAL_SHA384 */ 168 #ifdef CONFIG_INTERNAL_SHA512 169 case CRYPTO_HASH_ALG_SHA512: 170 sha512_process(&ctx->u.sha512, data, len); 171 break; 172 #endif /* CONFIG_INTERNAL_SHA512 */ 173 default: 174 break; 175 } 176 } 177 178 179 int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len) 180 { 181 u8 k_pad[64]; 182 size_t i; 183 184 if (ctx == NULL) 185 return -2; 186 187 if (mac == NULL || len == NULL) { 188 os_free(ctx); 189 return 0; 190 } 191 192 switch (ctx->alg) { 193 case CRYPTO_HASH_ALG_MD5: 194 if (*len < 16) { 195 *len = 16; 196 os_free(ctx); 197 return -1; 198 } 199 *len = 16; 200 MD5Final(mac, &ctx->u.md5); 201 break; 202 case CRYPTO_HASH_ALG_SHA1: 203 if (*len < 20) { 204 *len = 20; 205 os_free(ctx); 206 return -1; 207 } 208 *len = 20; 209 SHA1Final(mac, &ctx->u.sha1); 210 break; 211 #ifdef CONFIG_SHA256 212 case CRYPTO_HASH_ALG_SHA256: 213 if (*len < 32) { 214 *len = 32; 215 os_free(ctx); 216 return -1; 217 } 218 *len = 32; 219 sha256_done(&ctx->u.sha256, mac); 220 break; 221 #endif /* CONFIG_SHA256 */ 222 #ifdef CONFIG_INTERNAL_SHA384 223 case CRYPTO_HASH_ALG_SHA384: 224 if (*len < 48) { 225 *len = 48; 226 os_free(ctx); 227 return -1; 228 } 229 *len = 48; 230 sha384_done(&ctx->u.sha384, mac); 231 break; 232 #endif /* CONFIG_INTERNAL_SHA384 */ 233 #ifdef CONFIG_INTERNAL_SHA512 234 case CRYPTO_HASH_ALG_SHA512: 235 if (*len < 64) { 236 *len = 64; 237 os_free(ctx); 238 return -1; 239 } 240 *len = 64; 241 sha512_done(&ctx->u.sha512, mac); 242 break; 243 #endif /* CONFIG_INTERNAL_SHA512 */ 244 case CRYPTO_HASH_ALG_HMAC_MD5: 245 if (*len < 16) { 246 *len = 16; 247 os_free(ctx); 248 return -1; 249 } 250 *len = 16; 251 252 MD5Final(mac, &ctx->u.md5); 253 254 os_memcpy(k_pad, ctx->key, ctx->key_len); 255 os_memset(k_pad + ctx->key_len, 0, 256 sizeof(k_pad) - ctx->key_len); 257 for (i = 0; i < sizeof(k_pad); i++) 258 k_pad[i] ^= 0x5c; 259 MD5Init(&ctx->u.md5); 260 MD5Update(&ctx->u.md5, k_pad, sizeof(k_pad)); 261 MD5Update(&ctx->u.md5, mac, 16); 262 MD5Final(mac, &ctx->u.md5); 263 break; 264 case CRYPTO_HASH_ALG_HMAC_SHA1: 265 if (*len < 20) { 266 *len = 20; 267 os_free(ctx); 268 return -1; 269 } 270 *len = 20; 271 272 SHA1Final(mac, &ctx->u.sha1); 273 274 os_memcpy(k_pad, ctx->key, ctx->key_len); 275 os_memset(k_pad + ctx->key_len, 0, 276 sizeof(k_pad) - ctx->key_len); 277 for (i = 0; i < sizeof(k_pad); i++) 278 k_pad[i] ^= 0x5c; 279 SHA1Init(&ctx->u.sha1); 280 SHA1Update(&ctx->u.sha1, k_pad, sizeof(k_pad)); 281 SHA1Update(&ctx->u.sha1, mac, 20); 282 SHA1Final(mac, &ctx->u.sha1); 283 break; 284 #ifdef CONFIG_SHA256 285 case CRYPTO_HASH_ALG_HMAC_SHA256: 286 if (*len < 32) { 287 *len = 32; 288 os_free(ctx); 289 return -1; 290 } 291 *len = 32; 292 293 sha256_done(&ctx->u.sha256, mac); 294 295 os_memcpy(k_pad, ctx->key, ctx->key_len); 296 os_memset(k_pad + ctx->key_len, 0, 297 sizeof(k_pad) - ctx->key_len); 298 for (i = 0; i < sizeof(k_pad); i++) 299 k_pad[i] ^= 0x5c; 300 sha256_init(&ctx->u.sha256); 301 sha256_process(&ctx->u.sha256, k_pad, sizeof(k_pad)); 302 sha256_process(&ctx->u.sha256, mac, 32); 303 sha256_done(&ctx->u.sha256, mac); 304 break; 305 #endif /* CONFIG_SHA256 */ 306 default: 307 os_free(ctx); 308 return -1; 309 } 310 311 os_free(ctx); 312 313 return 0; 314 } 315 316 317 int crypto_global_init(void) 318 { 319 return 0; 320 } 321 322 323 void crypto_global_deinit(void) 324 { 325 } 326