Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 14 Mar 2013 16:33:43 +0000 (UTC)
From:      Andre Oppermann <andre@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r248270 - in user/andre/tcp-ao/sys/crypto: cmac hmac
Message-ID:  <201303141633.r2EGXhOf035667@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: andre
Date: Thu Mar 14 16:33:43 2013
New Revision: 248270
URL: http://svnweb.freebsd.org/changeset/base/248270

Log:
  Add HMAC and CMAC functions from OpenBSD:
  
   HMAC_MD5
   HMAC_SHA1
   HMAC_SHA256
   AES_CMAC
  
  This is a pure copy of the files.  Any adjustments to FreeBSD will happen
  in later commits.
  
  Note: Our crypto code and support functions are scattered in different places.
  This layout should be reconsidered at a later point in time.
  
  Sponsored by:	Juniper Networks

Added:
  user/andre/tcp-ao/sys/crypto/cmac/
  user/andre/tcp-ao/sys/crypto/cmac/cmac.c
  user/andre/tcp-ao/sys/crypto/cmac/cmac.h
  user/andre/tcp-ao/sys/crypto/hmac/
  user/andre/tcp-ao/sys/crypto/hmac/hmac.c
  user/andre/tcp-ao/sys/crypto/hmac/hmac.h

Added: user/andre/tcp-ao/sys/crypto/cmac/cmac.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/andre/tcp-ao/sys/crypto/cmac/cmac.c	Thu Mar 14 16:33:43 2013	(r248270)
@@ -0,0 +1,120 @@
+/*	$OpenBSD: cmac.c,v 1.2 2011/01/11 15:42:05 deraadt Exp $	*/
+
+/*-
+ * Copyright (c) 2008 Damien Bergamini <damien.bergamini@free.fr>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This code implements the CMAC (Cipher-based Message Authentication)
+ * algorithm described in FIPS SP800-38B using the AES-128 cipher.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <crypto/rijndael.h>
+#include <crypto/cmac.h>
+
+#define LSHIFT(v, r) do {					\
+	int i;							\
+	for (i = 0; i < 15; i++)				\
+		(r)[i] = (v)[i] << 1 | (v)[i + 1] >> 7;		\
+	(r)[15] = (v)[15] << 1;					\
+} while (0)
+
+#define XOR(v, r) do {						\
+	int i;							\
+	for (i = 0; i < 16; i++)				\
+		(r)[i] ^= (v)[i];				\
+} while (0)
+
+void
+AES_CMAC_Init(AES_CMAC_CTX *ctx)
+{
+	memset(ctx->X, 0, sizeof ctx->X);
+	ctx->M_n = 0;
+}
+
+void
+AES_CMAC_SetKey(AES_CMAC_CTX *ctx, const u_int8_t key[AES_CMAC_KEY_LENGTH])
+{
+	rijndael_set_key_enc_only(&ctx->rijndael, key, 128);
+}
+
+void
+AES_CMAC_Update(AES_CMAC_CTX *ctx, const u_int8_t *data, u_int len)
+{
+	u_int mlen;
+
+	if (ctx->M_n > 0) {
+		mlen = MIN(16 - ctx->M_n, len);
+		memcpy(ctx->M_last + ctx->M_n, data, mlen);
+		ctx->M_n += mlen;
+		if (ctx->M_n < 16 || len == mlen)
+			return;
+		XOR(ctx->M_last, ctx->X);
+		rijndael_encrypt(&ctx->rijndael, ctx->X, ctx->X);
+		data += mlen;
+		len -= mlen;
+	}
+	while (len > 16) {	/* not last block */
+		XOR(data, ctx->X);
+		rijndael_encrypt(&ctx->rijndael, ctx->X, ctx->X);
+		data += 16;
+		len -= 16;
+	}
+	/* potential last block, save it */
+	memcpy(ctx->M_last, data, len);
+	ctx->M_n = len;
+}
+
+void
+AES_CMAC_Final(u_int8_t digest[AES_CMAC_DIGEST_LENGTH], AES_CMAC_CTX *ctx)
+{
+	u_int8_t K[16];
+
+	/* generate subkey K1 */
+	memset(K, 0, sizeof K);
+	rijndael_encrypt(&ctx->rijndael, K, K);
+
+	if (K[0] & 0x80) {
+		LSHIFT(K, K);
+		K[15] ^= 0x87;
+	} else
+		LSHIFT(K, K);
+
+	if (ctx->M_n == 16) {
+		/* last block was a complete block */
+		XOR(K, ctx->M_last);
+	} else {
+		/* generate subkey K2 */
+		if (K[0] & 0x80) {
+			LSHIFT(K, K);
+			K[15] ^= 0x87;
+		} else
+			LSHIFT(K, K);
+
+		/* padding(M_last) */
+		ctx->M_last[ctx->M_n] = 0x80;
+		while (++ctx->M_n < 16)
+			ctx->M_last[ctx->M_n] = 0;
+
+		XOR(K, ctx->M_last);
+	}
+	XOR(ctx->M_last, ctx->X);
+	rijndael_encrypt(&ctx->rijndael, ctx->X, digest);
+
+	explicit_bzero(K, sizeof K);
+}

Added: user/andre/tcp-ao/sys/crypto/cmac/cmac.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/andre/tcp-ao/sys/crypto/cmac/cmac.h	Thu Mar 14 16:33:43 2013	(r248270)
@@ -0,0 +1,41 @@
+/*	$OpenBSD: cmac.h,v 1.2 2012/12/05 23:20:15 deraadt Exp $	*/
+
+/*-
+ * Copyright (c) 2008 Damien Bergamini <damien.bergamini@free.fr>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _CMAC_H_
+#define _CMAC_H_
+
+#define AES_CMAC_KEY_LENGTH	16
+#define AES_CMAC_DIGEST_LENGTH	16
+
+typedef struct _AES_CMAC_CTX {
+	rijndael_ctx	rijndael;
+	u_int8_t	X[16];
+	u_int8_t	M_last[16];
+	u_int		M_n;
+} AES_CMAC_CTX;
+
+__BEGIN_DECLS
+void	 AES_CMAC_Init(AES_CMAC_CTX *);
+void	 AES_CMAC_SetKey(AES_CMAC_CTX *, const u_int8_t [AES_CMAC_KEY_LENGTH]);
+void	 AES_CMAC_Update(AES_CMAC_CTX *, const u_int8_t *, u_int)
+		__attribute__((__bounded__(__string__,2,3)));
+void	 AES_CMAC_Final(u_int8_t [AES_CMAC_DIGEST_LENGTH], AES_CMAC_CTX *)
+		__attribute__((__bounded__(__minbytes__,1,AES_CMAC_DIGEST_LENGTH)));
+__END_DECLS
+
+#endif /* _CMAC_H_ */

Added: user/andre/tcp-ao/sys/crypto/hmac/hmac.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/andre/tcp-ao/sys/crypto/hmac/hmac.c	Thu Mar 14 16:33:43 2013	(r248270)
@@ -0,0 +1,192 @@
+/*	$OpenBSD: hmac.c,v 1.3 2011/01/11 15:42:05 deraadt Exp $	*/
+
+/*-
+ * Copyright (c) 2008 Damien Bergamini <damien.bergamini@free.fr>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This code implements the HMAC algorithm described in RFC 2104 using
+ * the MD5, SHA1 and SHA-256 hash functions.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <crypto/md5.h>
+#include <crypto/sha1.h>
+#include <crypto/sha2.h>
+#include <crypto/hmac.h>
+
+void
+HMAC_MD5_Init(HMAC_MD5_CTX *ctx, const u_int8_t *key, u_int key_len)
+{
+	u_int8_t k_ipad[MD5_BLOCK_LENGTH];
+	int i;
+
+	if (key_len > MD5_BLOCK_LENGTH) {
+		MD5Init(&ctx->ctx);
+		MD5Update(&ctx->ctx, key, key_len);
+		MD5Final(ctx->key, &ctx->ctx);
+		ctx->key_len = MD5_DIGEST_LENGTH;
+	} else {
+		bcopy(key, ctx->key, key_len);
+		ctx->key_len = key_len;
+	}
+
+	bzero(k_ipad, MD5_BLOCK_LENGTH);
+	bcopy(ctx->key, k_ipad, ctx->key_len);
+	for (i = 0; i < MD5_BLOCK_LENGTH; i++)
+		k_ipad[i] ^= 0x36;
+
+	MD5Init(&ctx->ctx);
+	MD5Update(&ctx->ctx, k_ipad, MD5_BLOCK_LENGTH);
+
+	explicit_bzero(k_ipad, sizeof k_ipad);
+}
+
+void
+HMAC_MD5_Update(HMAC_MD5_CTX *ctx, const u_int8_t *data, u_int len)
+{
+	MD5Update(&ctx->ctx, data, len);
+}
+
+void
+HMAC_MD5_Final(u_int8_t digest[MD5_DIGEST_LENGTH], HMAC_MD5_CTX *ctx)
+{
+	u_int8_t k_opad[MD5_BLOCK_LENGTH];
+	int i;
+
+	MD5Final(digest, &ctx->ctx);
+
+	bzero(k_opad, MD5_BLOCK_LENGTH);
+	bcopy(ctx->key, k_opad, ctx->key_len);
+	for (i = 0; i < MD5_BLOCK_LENGTH; i++)
+		k_opad[i] ^= 0x5c;
+
+	MD5Init(&ctx->ctx);
+	MD5Update(&ctx->ctx, k_opad, MD5_BLOCK_LENGTH);
+	MD5Update(&ctx->ctx, digest, MD5_DIGEST_LENGTH);
+	MD5Final(digest, &ctx->ctx);
+
+	explicit_bzero(k_opad, sizeof k_opad);
+}
+
+void
+HMAC_SHA1_Init(HMAC_SHA1_CTX *ctx, const u_int8_t *key, u_int key_len)
+{
+	u_int8_t k_ipad[SHA1_BLOCK_LENGTH];
+	int i;
+
+	if (key_len > SHA1_BLOCK_LENGTH) {
+		SHA1Init(&ctx->ctx);
+		SHA1Update(&ctx->ctx, key, key_len);
+		SHA1Final(ctx->key, &ctx->ctx);
+		ctx->key_len = SHA1_DIGEST_LENGTH;
+	} else {
+		bcopy(key, ctx->key, key_len);
+		ctx->key_len = key_len;
+	}
+
+	bzero(k_ipad, SHA1_BLOCK_LENGTH);
+	bcopy(ctx->key, k_ipad, ctx->key_len);
+	for (i = 0; i < SHA1_BLOCK_LENGTH; i++)
+		k_ipad[i] ^= 0x36;
+
+	SHA1Init(&ctx->ctx);
+	SHA1Update(&ctx->ctx, k_ipad, SHA1_BLOCK_LENGTH);
+
+	explicit_bzero(k_ipad, sizeof k_ipad);
+}
+
+void
+HMAC_SHA1_Update(HMAC_SHA1_CTX *ctx, const u_int8_t *data, u_int len)
+{
+	SHA1Update(&ctx->ctx, data, len);
+}
+
+void
+HMAC_SHA1_Final(u_int8_t digest[SHA1_DIGEST_LENGTH], HMAC_SHA1_CTX *ctx)
+{
+	u_int8_t k_opad[SHA1_BLOCK_LENGTH];
+	int i;
+
+	SHA1Final(digest, &ctx->ctx);
+
+	bzero(k_opad, SHA1_BLOCK_LENGTH);
+	bcopy(ctx->key, k_opad, ctx->key_len);
+	for (i = 0; i < SHA1_BLOCK_LENGTH; i++)
+		k_opad[i] ^= 0x5c;
+
+	SHA1Init(&ctx->ctx);
+	SHA1Update(&ctx->ctx, k_opad, SHA1_BLOCK_LENGTH);
+	SHA1Update(&ctx->ctx, digest, SHA1_DIGEST_LENGTH);
+	SHA1Final(digest, &ctx->ctx);
+
+	explicit_bzero(k_opad, sizeof k_opad);
+}
+
+void
+HMAC_SHA256_Init(HMAC_SHA256_CTX *ctx, const u_int8_t *key, u_int key_len)
+{
+	u_int8_t k_ipad[SHA256_BLOCK_LENGTH];
+	int i;
+
+	if (key_len > SHA256_BLOCK_LENGTH) {
+		SHA256Init(&ctx->ctx);
+		SHA256Update(&ctx->ctx, key, key_len);
+		SHA256Final(ctx->key, &ctx->ctx);
+		ctx->key_len = SHA256_DIGEST_LENGTH;
+	} else {
+		bcopy(key, ctx->key, key_len);
+		ctx->key_len = key_len;
+	}
+
+	bzero(k_ipad, SHA256_BLOCK_LENGTH);
+	bcopy(ctx->key, k_ipad, ctx->key_len);
+	for (i = 0; i < SHA256_BLOCK_LENGTH; i++)
+		k_ipad[i] ^= 0x36;
+
+	SHA256Init(&ctx->ctx);
+	SHA256Update(&ctx->ctx, k_ipad, SHA256_BLOCK_LENGTH);
+
+	explicit_bzero(k_ipad, sizeof k_ipad);
+}
+
+void
+HMAC_SHA256_Update(HMAC_SHA256_CTX *ctx, const u_int8_t *data, u_int len)
+{
+	SHA256Update(&ctx->ctx, data, len);
+}
+
+void
+HMAC_SHA256_Final(u_int8_t digest[SHA256_DIGEST_LENGTH], HMAC_SHA256_CTX *ctx)
+{
+	u_int8_t k_opad[SHA256_BLOCK_LENGTH];
+	int i;
+
+	SHA256Final(digest, &ctx->ctx);
+
+	bzero(k_opad, SHA256_BLOCK_LENGTH);
+	bcopy(ctx->key, k_opad, ctx->key_len);
+	for (i = 0; i < SHA256_BLOCK_LENGTH; i++)
+		k_opad[i] ^= 0x5c;
+
+	SHA256Init(&ctx->ctx);
+	SHA256Update(&ctx->ctx, k_opad, SHA256_BLOCK_LENGTH);
+	SHA256Update(&ctx->ctx, digest, SHA256_DIGEST_LENGTH);
+	SHA256Final(digest, &ctx->ctx);
+
+	explicit_bzero(k_opad, sizeof k_opad);
+}

Added: user/andre/tcp-ao/sys/crypto/hmac/hmac.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/andre/tcp-ao/sys/crypto/hmac/hmac.h	Thu Mar 14 16:33:43 2013	(r248270)
@@ -0,0 +1,65 @@
+/*	$OpenBSD: hmac.h,v 1.3 2012/12/05 23:20:15 deraadt Exp $	*/
+
+/*-
+ * Copyright (c) 2008 Damien Bergamini <damien.bergamini@free.fr>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _HMAC_H_
+#define _HMAC_H_
+
+typedef struct _HMAC_MD5_CTX {
+	MD5_CTX		ctx;
+	u_int8_t	key[MD5_BLOCK_LENGTH];
+	u_int		key_len;
+} HMAC_MD5_CTX;
+
+typedef struct _HMAC_SHA1_CTX {
+	SHA1_CTX	ctx;
+	u_int8_t	key[SHA1_BLOCK_LENGTH];
+	u_int		key_len;
+} HMAC_SHA1_CTX;
+
+typedef struct _HMAC_SHA256_CTX {
+	SHA2_CTX	ctx;
+	u_int8_t	key[SHA256_BLOCK_LENGTH];
+	u_int		key_len;
+} HMAC_SHA256_CTX;
+
+__BEGIN_DECLS
+
+void	 HMAC_MD5_Init(HMAC_MD5_CTX *, const u_int8_t *, u_int)
+		__attribute__((__bounded__(__string__,2,3)));
+void	 HMAC_MD5_Update(HMAC_MD5_CTX *, const u_int8_t *, u_int)
+		__attribute__((__bounded__(__string__,2,3)));
+void	 HMAC_MD5_Final(u_int8_t [MD5_DIGEST_LENGTH], HMAC_MD5_CTX *)
+		__attribute__((__bounded__(__minbytes__,1,MD5_DIGEST_LENGTH)));
+
+void	 HMAC_SHA1_Init(HMAC_SHA1_CTX *, const u_int8_t *, u_int)
+		__attribute__((__bounded__(__string__,2,3)));
+void	 HMAC_SHA1_Update(HMAC_SHA1_CTX *, const u_int8_t *, u_int)
+		__attribute__((__bounded__(__string__,2,3)));
+void	 HMAC_SHA1_Final(u_int8_t [SHA1_DIGEST_LENGTH], HMAC_SHA1_CTX *)
+		__attribute__((__bounded__(__minbytes__,1,SHA1_DIGEST_LENGTH)));
+
+void	 HMAC_SHA256_Init(HMAC_SHA256_CTX *, const u_int8_t *, u_int)
+		__attribute__((__bounded__(__string__,2,3)));
+void	 HMAC_SHA256_Update(HMAC_SHA256_CTX *, const u_int8_t *, u_int)
+		__attribute__((__bounded__(__string__,2,3)));
+void	 HMAC_SHA256_Final(u_int8_t [SHA256_DIGEST_LENGTH], HMAC_SHA256_CTX *)
+		__attribute__((__bounded__(__minbytes__,1,SHA256_DIGEST_LENGTH)));
+
+__END_DECLS
+
+#endif	/* _HMAC_H_ */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201303141633.r2EGXhOf035667>