summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorReyk Floeter <reyk@cvs.openbsd.org>2006-03-21 18:40:55 +0000
committerReyk Floeter <reyk@cvs.openbsd.org>2006-03-21 18:40:55 +0000
commit8767ac816d870fc31ad15b6dab06c6abb82878ea (patch)
tree804a7a605ea6be12095bfde5784f84222f9d9da8 /sys
parent8be52bf3f280d86a9655758a1887266d07e455fc (diff)
Implementation of the Michael MIC as defined in IEEE 802.11i for TKIP.
The MIC generates a weak 64bit digest protected by an additional key. Obviously, this digest alg is required for future IEEE 802.11i/WPA support. test vectors passed on alpha amd64 mvme68k mvme88k sgi sparc sparc64 vax i386 ok djm@
Diffstat (limited to 'sys')
-rw-r--r--sys/conf/files3
-rw-r--r--sys/crypto/michael.c87
-rw-r--r--sys/crypto/michael.h47
3 files changed, 136 insertions, 1 deletions
diff --git a/sys/conf/files b/sys/conf/files
index 6b91296b45d..54f6c748ff7 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -1,4 +1,4 @@
-# $OpenBSD: files,v 1.367 2006/03/12 00:18:07 brad Exp $
+# $OpenBSD: files,v 1.368 2006/03/21 18:40:54 reyk Exp $
# $NetBSD: files,v 1.87 1996/05/19 17:17:50 jonathan Exp $
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
@@ -782,6 +782,7 @@ file crypto/cryptosoft.c (inet & ipsec) | crypto
file crypto/xform.c (inet & ipsec) | crypto
file crypto/deflate.c (inet & ipsec) | crypto
file crypto/arc4.c wi | wlan
+file crypto/michael.c wlan
file netatalk/aarp.c netatalk
file netatalk/at_control.c netatalk
file netatalk/at_proto.c netatalk
diff --git a/sys/crypto/michael.c b/sys/crypto/michael.c
new file mode 100644
index 00000000000..8a4b6a31100
--- /dev/null
+++ b/sys/crypto/michael.c
@@ -0,0 +1,87 @@
+/* $OpenBSD: michael.c,v 1.1 2006/03/21 18:40:54 reyk Exp $ */
+
+/*
+ * Copyright (c) 2005, 2006 Reyk Floeter <reyk@openbsd.org>
+ *
+ * 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.
+ */
+
+/*
+ * Implementation of the Michael MIC as defined in IEEE 802.11i for TKIP.
+ * The MIC generates a 64bit digest, which shouldn't be used for any other
+ * applications except TKIP.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <crypto/michael.h>
+
+#define ROL(n, x) (((x) << (n)) | ((x) >> (32 - (n))))
+#define ROR(n, x) (((x) >> (n)) | ((x) << (32 - (n))))
+#define VAL32(x) (*((u_int32_t *)(x)))
+#define XSWAP(x) (((x) & 0xff00ff00UL) >> 8) | ((((x) & 0x00ff00ffUL) << 8))
+
+#define MICHAEL_BLOCK(l, r) do { \
+ r ^= ROL(17, l); \
+ l += r; \
+ r ^= XSWAP(l); \
+ l += r; \
+ r ^= ROL(3, l); \
+ l += r; \
+ r ^= ROR(2, l); \
+ l += r; \
+} while (0)
+
+void
+michael_init(MICHAEL_CTX *ctx)
+{
+ bzero(ctx, sizeof(MICHAEL_CTX));
+}
+
+void
+michael_update(MICHAEL_CTX *ctx, const u_int8_t *data, u_int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++) {
+ ctx->michael_state |= data[i] << (ctx->michael_count << 3);
+ ctx->michael_count++;
+
+ if (ctx->michael_count >= MICHAEL_RAW_BLOCK_LENGTH) {
+ ctx->michael_l ^= ctx->michael_state;
+ MICHAEL_BLOCK(ctx->michael_l, ctx->michael_r);
+ ctx->michael_state = ctx->michael_count = 0;
+ }
+ }
+}
+
+void
+michael_final(u_int8_t digest[MICHAEL_DIGEST_LENGTH], MICHAEL_CTX *ctx)
+{
+ u_int8_t pad[] = { 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+ michael_update(ctx, pad, sizeof(pad));
+
+ VAL32(digest) = letoh32(ctx->michael_l);
+ VAL32(digest + MICHAEL_RAW_BLOCK_LENGTH) = letoh32(ctx->michael_r);
+}
+
+void
+michael_key(const u_int8_t *key, MICHAEL_CTX *ctx)
+{
+ ctx->michael_l = ctx->michael_key[0] =
+ htole32(VAL32(key));
+ ctx->michael_r = ctx->michael_key[1] =
+ htole32(VAL32(key + MICHAEL_RAW_BLOCK_LENGTH));
+}
diff --git a/sys/crypto/michael.h b/sys/crypto/michael.h
new file mode 100644
index 00000000000..3b7c435842e
--- /dev/null
+++ b/sys/crypto/michael.h
@@ -0,0 +1,47 @@
+/* $OpenBSD: michael.h,v 1.1 2006/03/21 18:40:54 reyk Exp $ */
+
+/*
+ * Copyright (c) 2005, 2006 Reyk Floeter <reyk@openbsd.org>
+ *
+ * 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 _MICHAEL_H_
+#define _MICHAEL_H_
+
+#define MICHAEL_BLOCK_LENGTH 8
+#define MICHAEL_RAW_BLOCK_LENGTH 4
+#define MICHAEL_DIGEST_LENGTH 8
+
+typedef struct michael_context {
+ u_int32_t michael_key[2];
+ u_int32_t michael_l, michael_r;
+ u_int32_t michael_state;
+ u_int michael_count;
+} MICHAEL_CTX;
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+void michael_init(MICHAEL_CTX *);
+void michael_update(MICHAEL_CTX *, const u_int8_t *, u_int)
+ __attribute__((__bounded__(__buffer__, 2, 3)));
+void michael_final(u_int8_t [MICHAEL_DIGEST_LENGTH], MICHAEL_CTX *)
+ __attribute__((__bounded__(__minbytes__, 1,
+ MICHAEL_DIGEST_LENGTH)));
+void michael_key(const u_int8_t *, MICHAEL_CTX *)
+ __attribute__((__bounded__(__minbytes__, 1,
+ MICHAEL_BLOCK_LENGTH)));
+__END_DECLS
+
+#endif /* _MICHAEL_H_ */