Add SHA256-hash functions to generic crypto_hash_* functions
Signed-hostap: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
b32a8d1dfe
commit
dcff088df7
5 changed files with 115 additions and 20 deletions
|
@ -12,6 +12,7 @@ include ../lib.rules
|
||||||
CFLAGS += -DCONFIG_TLS_INTERNAL_CLIENT
|
CFLAGS += -DCONFIG_TLS_INTERNAL_CLIENT
|
||||||
CFLAGS += -DCONFIG_TLS_INTERNAL_SERVER
|
CFLAGS += -DCONFIG_TLS_INTERNAL_SERVER
|
||||||
#CFLAGS += -DALL_DH_GROUPS
|
#CFLAGS += -DALL_DH_GROUPS
|
||||||
|
CFLAGS += -DCONFIG_SHA256
|
||||||
|
|
||||||
LIB_OBJS= \
|
LIB_OBJS= \
|
||||||
aes-cbc.o \
|
aes-cbc.o \
|
||||||
|
|
|
@ -155,7 +155,8 @@ void aes_decrypt_deinit(void *ctx);
|
||||||
|
|
||||||
enum crypto_hash_alg {
|
enum crypto_hash_alg {
|
||||||
CRYPTO_HASH_ALG_MD5, CRYPTO_HASH_ALG_SHA1,
|
CRYPTO_HASH_ALG_MD5, CRYPTO_HASH_ALG_SHA1,
|
||||||
CRYPTO_HASH_ALG_HMAC_MD5, CRYPTO_HASH_ALG_HMAC_SHA1
|
CRYPTO_HASH_ALG_HMAC_MD5, CRYPTO_HASH_ALG_HMAC_SHA1,
|
||||||
|
CRYPTO_HASH_ALG_SHA256, CRYPTO_HASH_ALG_HMAC_SHA256
|
||||||
};
|
};
|
||||||
|
|
||||||
struct crypto_hash;
|
struct crypto_hash;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Crypto wrapper for internal crypto implementation
|
* Crypto wrapper for internal crypto implementation
|
||||||
* Copyright (c) 2006-2009, Jouni Malinen <j@w1.fi>
|
* Copyright (c) 2006-2011, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "crypto.h"
|
#include "crypto.h"
|
||||||
|
#include "sha256_i.h"
|
||||||
#include "sha1_i.h"
|
#include "sha1_i.h"
|
||||||
#include "md5_i.h"
|
#include "md5_i.h"
|
||||||
|
|
||||||
|
@ -24,6 +25,9 @@ struct crypto_hash {
|
||||||
union {
|
union {
|
||||||
struct MD5Context md5;
|
struct MD5Context md5;
|
||||||
struct SHA1Context sha1;
|
struct SHA1Context sha1;
|
||||||
|
#ifdef CONFIG_SHA256
|
||||||
|
struct sha256_state sha256;
|
||||||
|
#endif /* CONFIG_SHA256 */
|
||||||
} u;
|
} u;
|
||||||
u8 key[64];
|
u8 key[64];
|
||||||
size_t key_len;
|
size_t key_len;
|
||||||
|
@ -35,7 +39,7 @@ struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key,
|
||||||
{
|
{
|
||||||
struct crypto_hash *ctx;
|
struct crypto_hash *ctx;
|
||||||
u8 k_pad[64];
|
u8 k_pad[64];
|
||||||
u8 tk[20];
|
u8 tk[32];
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
ctx = os_zalloc(sizeof(*ctx));
|
ctx = os_zalloc(sizeof(*ctx));
|
||||||
|
@ -51,6 +55,11 @@ struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key,
|
||||||
case CRYPTO_HASH_ALG_SHA1:
|
case CRYPTO_HASH_ALG_SHA1:
|
||||||
SHA1Init(&ctx->u.sha1);
|
SHA1Init(&ctx->u.sha1);
|
||||||
break;
|
break;
|
||||||
|
#ifdef CONFIG_SHA256
|
||||||
|
case CRYPTO_HASH_ALG_SHA256:
|
||||||
|
sha256_init(&ctx->u.sha256);
|
||||||
|
break;
|
||||||
|
#endif /* CONFIG_SHA256 */
|
||||||
case CRYPTO_HASH_ALG_HMAC_MD5:
|
case CRYPTO_HASH_ALG_HMAC_MD5:
|
||||||
if (key_len > sizeof(k_pad)) {
|
if (key_len > sizeof(k_pad)) {
|
||||||
MD5Init(&ctx->u.md5);
|
MD5Init(&ctx->u.md5);
|
||||||
|
@ -89,6 +98,27 @@ struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key,
|
||||||
SHA1Init(&ctx->u.sha1);
|
SHA1Init(&ctx->u.sha1);
|
||||||
SHA1Update(&ctx->u.sha1, k_pad, sizeof(k_pad));
|
SHA1Update(&ctx->u.sha1, k_pad, sizeof(k_pad));
|
||||||
break;
|
break;
|
||||||
|
#ifdef CONFIG_SHA256
|
||||||
|
case CRYPTO_HASH_ALG_HMAC_SHA256:
|
||||||
|
if (key_len > sizeof(k_pad)) {
|
||||||
|
sha256_init(&ctx->u.sha256);
|
||||||
|
sha256_process(&ctx->u.sha256, key, key_len);
|
||||||
|
sha256_done(&ctx->u.sha256, tk);
|
||||||
|
key = tk;
|
||||||
|
key_len = 32;
|
||||||
|
}
|
||||||
|
os_memcpy(ctx->key, key, key_len);
|
||||||
|
ctx->key_len = key_len;
|
||||||
|
|
||||||
|
os_memcpy(k_pad, key, key_len);
|
||||||
|
if (key_len < sizeof(k_pad))
|
||||||
|
os_memset(k_pad + key_len, 0, sizeof(k_pad) - key_len);
|
||||||
|
for (i = 0; i < sizeof(k_pad); i++)
|
||||||
|
k_pad[i] ^= 0x36;
|
||||||
|
sha256_init(&ctx->u.sha256);
|
||||||
|
sha256_process(&ctx->u.sha256, k_pad, sizeof(k_pad));
|
||||||
|
break;
|
||||||
|
#endif /* CONFIG_SHA256 */
|
||||||
default:
|
default:
|
||||||
os_free(ctx);
|
os_free(ctx);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -112,6 +142,14 @@ void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len)
|
||||||
case CRYPTO_HASH_ALG_HMAC_SHA1:
|
case CRYPTO_HASH_ALG_HMAC_SHA1:
|
||||||
SHA1Update(&ctx->u.sha1, data, len);
|
SHA1Update(&ctx->u.sha1, data, len);
|
||||||
break;
|
break;
|
||||||
|
#ifdef CONFIG_SHA256
|
||||||
|
case CRYPTO_HASH_ALG_SHA256:
|
||||||
|
case CRYPTO_HASH_ALG_HMAC_SHA256:
|
||||||
|
sha256_process(&ctx->u.sha256, data, len);
|
||||||
|
break;
|
||||||
|
#endif /* CONFIG_SHA256 */
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,6 +186,17 @@ int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len)
|
||||||
*len = 20;
|
*len = 20;
|
||||||
SHA1Final(mac, &ctx->u.sha1);
|
SHA1Final(mac, &ctx->u.sha1);
|
||||||
break;
|
break;
|
||||||
|
#ifdef CONFIG_SHA256
|
||||||
|
case CRYPTO_HASH_ALG_SHA256:
|
||||||
|
if (*len < 32) {
|
||||||
|
*len = 32;
|
||||||
|
os_free(ctx);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
*len = 32;
|
||||||
|
sha256_done(&ctx->u.sha256, mac);
|
||||||
|
break;
|
||||||
|
#endif /* CONFIG_SHA256 */
|
||||||
case CRYPTO_HASH_ALG_HMAC_MD5:
|
case CRYPTO_HASH_ALG_HMAC_MD5:
|
||||||
if (*len < 16) {
|
if (*len < 16) {
|
||||||
*len = 16;
|
*len = 16;
|
||||||
|
@ -188,6 +237,31 @@ int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len)
|
||||||
SHA1Update(&ctx->u.sha1, mac, 20);
|
SHA1Update(&ctx->u.sha1, mac, 20);
|
||||||
SHA1Final(mac, &ctx->u.sha1);
|
SHA1Final(mac, &ctx->u.sha1);
|
||||||
break;
|
break;
|
||||||
|
#ifdef CONFIG_SHA256
|
||||||
|
case CRYPTO_HASH_ALG_HMAC_SHA256:
|
||||||
|
if (*len < 32) {
|
||||||
|
*len = 32;
|
||||||
|
os_free(ctx);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
*len = 32;
|
||||||
|
|
||||||
|
sha256_done(&ctx->u.sha256, mac);
|
||||||
|
|
||||||
|
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;
|
||||||
|
sha256_init(&ctx->u.sha256);
|
||||||
|
sha256_process(&ctx->u.sha256, k_pad, sizeof(k_pad));
|
||||||
|
sha256_process(&ctx->u.sha256, mac, 32);
|
||||||
|
sha256_done(&ctx->u.sha256, mac);
|
||||||
|
break;
|
||||||
|
#endif /* CONFIG_SHA256 */
|
||||||
|
default:
|
||||||
|
os_free(ctx);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
os_free(ctx);
|
os_free(ctx);
|
||||||
|
|
|
@ -16,21 +16,9 @@
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "sha256.h"
|
#include "sha256.h"
|
||||||
|
#include "sha256_i.h"
|
||||||
#include "crypto.h"
|
#include "crypto.h"
|
||||||
|
|
||||||
#define SHA256_BLOCK_SIZE 64
|
|
||||||
|
|
||||||
struct sha256_state {
|
|
||||||
u64 length;
|
|
||||||
u32 state[8], curlen;
|
|
||||||
u8 buf[SHA256_BLOCK_SIZE];
|
|
||||||
};
|
|
||||||
|
|
||||||
static void sha256_init(struct sha256_state *md);
|
|
||||||
static int sha256_process(struct sha256_state *md, const unsigned char *in,
|
|
||||||
unsigned long inlen);
|
|
||||||
static int sha256_done(struct sha256_state *md, unsigned char *out);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sha256_vector - SHA256 hash for data vector
|
* sha256_vector - SHA256 hash for data vector
|
||||||
|
@ -139,7 +127,7 @@ static int sha256_compress(struct sha256_state *md, unsigned char *buf)
|
||||||
|
|
||||||
|
|
||||||
/* Initialize the hash state */
|
/* Initialize the hash state */
|
||||||
static void sha256_init(struct sha256_state *md)
|
void sha256_init(struct sha256_state *md)
|
||||||
{
|
{
|
||||||
md->curlen = 0;
|
md->curlen = 0;
|
||||||
md->length = 0;
|
md->length = 0;
|
||||||
|
@ -160,8 +148,8 @@ static void sha256_init(struct sha256_state *md)
|
||||||
@param inlen The length of the data (octets)
|
@param inlen The length of the data (octets)
|
||||||
@return CRYPT_OK if successful
|
@return CRYPT_OK if successful
|
||||||
*/
|
*/
|
||||||
static int sha256_process(struct sha256_state *md, const unsigned char *in,
|
int sha256_process(struct sha256_state *md, const unsigned char *in,
|
||||||
unsigned long inlen)
|
unsigned long inlen)
|
||||||
{
|
{
|
||||||
unsigned long n;
|
unsigned long n;
|
||||||
|
|
||||||
|
@ -200,7 +188,7 @@ static int sha256_process(struct sha256_state *md, const unsigned char *in,
|
||||||
@param out [out] The destination of the hash (32 bytes)
|
@param out [out] The destination of the hash (32 bytes)
|
||||||
@return CRYPT_OK if successful
|
@return CRYPT_OK if successful
|
||||||
*/
|
*/
|
||||||
static int sha256_done(struct sha256_state *md, unsigned char *out)
|
int sha256_done(struct sha256_state *md, unsigned char *out)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
|
31
src/crypto/sha256_i.h
Normal file
31
src/crypto/sha256_i.h
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* SHA-256 internal definitions
|
||||||
|
* Copyright (c) 2003-2011, 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SHA256_I_H
|
||||||
|
#define SHA256_I_H
|
||||||
|
|
||||||
|
#define SHA256_BLOCK_SIZE 64
|
||||||
|
|
||||||
|
struct sha256_state {
|
||||||
|
u64 length;
|
||||||
|
u32 state[8], curlen;
|
||||||
|
u8 buf[SHA256_BLOCK_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
|
void sha256_init(struct sha256_state *md);
|
||||||
|
int sha256_process(struct sha256_state *md, const unsigned char *in,
|
||||||
|
unsigned long inlen);
|
||||||
|
int sha256_done(struct sha256_state *md, unsigned char *out);
|
||||||
|
|
||||||
|
#endif /* SHA256_I_H */
|
Loading…
Reference in a new issue