]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Add SHA256-hash functions to generic crypto_hash_* functions
authorJouni Malinen <j@w1.fi>
Sun, 27 Nov 2011 19:00:59 +0000 (21:00 +0200)
committerJouni Malinen <j@w1.fi>
Sun, 27 Nov 2011 19:10:06 +0000 (21:10 +0200)
Signed-hostap: Jouni Malinen <j@w1.fi>

src/crypto/Makefile
src/crypto/crypto.h
src/crypto/crypto_internal.c
src/crypto/sha256-internal.c
src/crypto/sha256_i.h [new file with mode: 0644]

index 0454827b871dd01680c2ae0a25f600926e6da716..290fa677a16a2ab32323d8dc2e456036ada6654d 100644 (file)
@@ -12,6 +12,7 @@ include ../lib.rules
 CFLAGS += -DCONFIG_TLS_INTERNAL_CLIENT
 CFLAGS += -DCONFIG_TLS_INTERNAL_SERVER
 #CFLAGS += -DALL_DH_GROUPS
+CFLAGS += -DCONFIG_SHA256
 
 LIB_OBJS= \
        aes-cbc.o \
index 587b5a95747fc993e6c56779085b02ba7fa5306f..6dca191cb81fbda4e222a70ddb5fbad509c615f8 100644 (file)
@@ -155,7 +155,8 @@ void aes_decrypt_deinit(void *ctx);
 
 enum crypto_hash_alg {
        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;
index 5f715a8311e25ba0b3b6a1cfd68bd40aa54f8c25..9362fe10831568c74199c42db331cee93164ce3d 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * 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
  * it under the terms of the GNU General Public License version 2 as
@@ -16,6 +16,7 @@
 
 #include "common.h"
 #include "crypto.h"
+#include "sha256_i.h"
 #include "sha1_i.h"
 #include "md5_i.h"
 
@@ -24,6 +25,9 @@ struct crypto_hash {
        union {
                struct MD5Context md5;
                struct SHA1Context sha1;
+#ifdef CONFIG_SHA256
+               struct sha256_state sha256;
+#endif /* CONFIG_SHA256 */
        } u;
        u8 key[64];
        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;
        u8 k_pad[64];
-       u8 tk[20];
+       u8 tk[32];
        size_t i;
 
        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:
                SHA1Init(&ctx->u.sha1);
                break;
+#ifdef CONFIG_SHA256
+       case CRYPTO_HASH_ALG_SHA256:
+               sha256_init(&ctx->u.sha256);
+               break;
+#endif /* CONFIG_SHA256 */
        case CRYPTO_HASH_ALG_HMAC_MD5:
                if (key_len > sizeof(k_pad)) {
                        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);
                SHA1Update(&ctx->u.sha1, k_pad, sizeof(k_pad));
                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:
                os_free(ctx);
                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:
                SHA1Update(&ctx->u.sha1, data, len);
                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;
                SHA1Final(mac, &ctx->u.sha1);
                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:
                if (*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);
                SHA1Final(mac, &ctx->u.sha1);
                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);
index c3a74c3967a57673e54be89d72d64792bd8e3cc2..ef5751dc1d41724b38f272f7ff50c76f82e5e23e 100644 (file)
 
 #include "common.h"
 #include "sha256.h"
+#include "sha256_i.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
@@ -139,7 +127,7 @@ static int sha256_compress(struct sha256_state *md, unsigned char *buf)
 
 
 /* Initialize the hash state */
-static void sha256_init(struct sha256_state *md)
+void sha256_init(struct sha256_state *md)
 {
        md->curlen = 0;
        md->length = 0;
@@ -160,8 +148,8 @@ static void sha256_init(struct sha256_state *md)
    @param inlen  The length of the data (octets)
    @return CRYPT_OK if successful
 */
-static int sha256_process(struct sha256_state *md, const unsigned char *in,
-                         unsigned long inlen)
+int sha256_process(struct sha256_state *md, const unsigned char *in,
+                  unsigned long inlen)
 {
        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)
    @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;
 
diff --git a/src/crypto/sha256_i.h b/src/crypto/sha256_i.h
new file mode 100644 (file)
index 0000000..20ae488
--- /dev/null
@@ -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 */