+++ /dev/null
-/*
- * Crypto wrapper for internal crypto implementation
- * Copyright (c) 2006-2009, Jouni Malinen <j@w1.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- * See README and COPYING for more details.
- */
-
-#include "includes.h"
-
-#include "common.h"
-#include "crypto.h"
-#include "sha1_i.h"
-#include "md5_i.h"
-
-struct crypto_hash {
- enum crypto_hash_alg alg;
- union {
- struct MD5Context md5;
- struct SHA1Context sha1;
- } u;
- u8 key[64];
- size_t key_len;
-};
-
-
-struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key,
- size_t key_len)
-{
- struct crypto_hash *ctx;
- u8 k_pad[64];
- u8 tk[20];
- size_t i;
-
- ctx = os_zalloc(sizeof(*ctx));
- if (ctx == NULL)
- return NULL;
-
- ctx->alg = alg;
-
- switch (alg) {
- case CRYPTO_HASH_ALG_MD5:
- MD5Init(&ctx->u.md5);
- break;
- case CRYPTO_HASH_ALG_SHA1:
- SHA1Init(&ctx->u.sha1);
- break;
- case CRYPTO_HASH_ALG_HMAC_MD5:
- if (key_len > sizeof(k_pad)) {
- MD5Init(&ctx->u.md5);
- MD5Update(&ctx->u.md5, key, key_len);
- MD5Final(tk, &ctx->u.md5);
- key = tk;
- key_len = 16;
- }
- os_memcpy(ctx->key, key, key_len);
- ctx->key_len = key_len;
-
- os_memcpy(k_pad, key, key_len);
- os_memset(k_pad + key_len, 0, sizeof(k_pad) - key_len);
- for (i = 0; i < sizeof(k_pad); i++)
- k_pad[i] ^= 0x36;
- MD5Init(&ctx->u.md5);
- MD5Update(&ctx->u.md5, k_pad, sizeof(k_pad));
- break;
- case CRYPTO_HASH_ALG_HMAC_SHA1:
- if (key_len > sizeof(k_pad)) {
- SHA1Init(&ctx->u.sha1);
- SHA1Update(&ctx->u.sha1, key, key_len);
- SHA1Final(tk, &ctx->u.sha1);
- key = tk;
- key_len = 20;
- }
- os_memcpy(ctx->key, key, key_len);
- ctx->key_len = key_len;
-
- os_memcpy(k_pad, key, key_len);
- os_memset(k_pad + key_len, 0, sizeof(k_pad) - key_len);
- for (i = 0; i < sizeof(k_pad); i++)
- k_pad[i] ^= 0x36;
- SHA1Init(&ctx->u.sha1);
- SHA1Update(&ctx->u.sha1, k_pad, sizeof(k_pad));
- break;
- default:
- os_free(ctx);
- return NULL;
- }
-
- return ctx;
-}
-
-
-void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len)
-{
- if (ctx == NULL)
- return;
-
- switch (ctx->alg) {
- case CRYPTO_HASH_ALG_MD5:
- case CRYPTO_HASH_ALG_HMAC_MD5:
- MD5Update(&ctx->u.md5, data, len);
- break;
- case CRYPTO_HASH_ALG_SHA1:
- case CRYPTO_HASH_ALG_HMAC_SHA1:
- SHA1Update(&ctx->u.sha1, data, len);
- break;
- }
-}
-
-
-int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len)
-{
- u8 k_pad[64];
- size_t i;
-
- if (ctx == NULL)
- return -2;
-
- if (mac == NULL || len == NULL) {
- os_free(ctx);
- return 0;
- }
-
- switch (ctx->alg) {
- case CRYPTO_HASH_ALG_MD5:
- if (*len < 16) {
- *len = 16;
- os_free(ctx);
- return -1;
- }
- *len = 16;
- MD5Final(mac, &ctx->u.md5);
- break;
- case CRYPTO_HASH_ALG_SHA1:
- if (*len < 20) {
- *len = 20;
- os_free(ctx);
- return -1;
- }
- *len = 20;
- SHA1Final(mac, &ctx->u.sha1);
- break;
- case CRYPTO_HASH_ALG_HMAC_MD5:
- if (*len < 16) {
- *len = 16;
- os_free(ctx);
- return -1;
- }
- *len = 16;
-
- MD5Final(mac, &ctx->u.md5);
-
- os_memcpy(k_pad, ctx->key, ctx->key_len);
- os_memset(k_pad + ctx->key_len, 0,
- sizeof(k_pad) - ctx->key_len);
- for (i = 0; i < sizeof(k_pad); i++)
- k_pad[i] ^= 0x5c;
- MD5Init(&ctx->u.md5);
- MD5Update(&ctx->u.md5, k_pad, sizeof(k_pad));
- MD5Update(&ctx->u.md5, mac, 16);
- MD5Final(mac, &ctx->u.md5);
- break;
- case CRYPTO_HASH_ALG_HMAC_SHA1:
- if (*len < 20) {
- *len = 20;
- os_free(ctx);
- return -1;
- }
- *len = 20;
-
- SHA1Final(mac, &ctx->u.sha1);
-
- os_memcpy(k_pad, ctx->key, ctx->key_len);
- os_memset(k_pad + ctx->key_len, 0,
- sizeof(k_pad) - ctx->key_len);
- for (i = 0; i < sizeof(k_pad); i++)
- k_pad[i] ^= 0x5c;
- SHA1Init(&ctx->u.sha1);
- SHA1Update(&ctx->u.sha1, k_pad, sizeof(k_pad));
- SHA1Update(&ctx->u.sha1, mac, 20);
- SHA1Final(mac, &ctx->u.sha1);
- break;
- }
-
- os_free(ctx);
-
- return 0;
-}
-
-
-int crypto_global_init(void)
-{
- return 0;
-}
-
-
-void crypto_global_deinit(void)
-{
-}