summaryrefslogtreecommitdiffstats
path: root/tboot/include/vmac.h
diff options
context:
space:
mode:
Diffstat (limited to 'tboot/include/vmac.h')
-rw-r--r--tboot/include/vmac.h168
1 files changed, 168 insertions, 0 deletions
diff --git a/tboot/include/vmac.h b/tboot/include/vmac.h
new file mode 100644
index 0000000..6104668
--- /dev/null
+++ b/tboot/include/vmac.h
@@ -0,0 +1,168 @@
+#ifndef HEADER_VMAC_H
+#define HEADER_VMAC_H
+
+/* --------------------------------------------------------------------------
+ * VMAC and VHASH Implementation by Ted Krovetz (tdk@acm.org) and Wei Dai.
+ * This implementation is herby placed in the public domain.
+ * The authors offers no warranty. Use at your own risk.
+ * Please send bug reports to the authors.
+ * Last modified: 17 APR 08, 1700 PDT
+ * ----------------------------------------------------------------------- */
+
+/* --------------------------------------------------------------------------
+ * User definable settings.
+ * ----------------------------------------------------------------------- */
+#define VMAC_TAG_LEN 64 /* Must be 64 or 128 - 64 sufficient for most */
+#define VMAC_KEY_LEN 128 /* Must be 128, 192 or 256 */
+#define VMAC_NHBYTES 4096/* Must 2^i for any 3 < i < 13. Standard = 128 */
+#define VMAC_PREFER_BIG_ENDIAN 0 /* Prefer non-x86 */
+
+#define VMAC_USE_OPENSSL 0 /* Set to non-zero to use OpenSSL's AES */
+#define VMAC_CACHE_NONCES 1 /* Set to non-zero to cause caching */
+ /* of consecutive nonces on 64-bit tags */
+
+#define VMAC_RUN_TESTS 0 /* Set to non-zero to check vectors and speed */
+#define VMAC_HZ (448e6) /* Set to hz of host machine to get speed */
+#define VMAC_HASH_ONLY 0 /* Set to non-zero to time hash only (not-mac) */
+/* Speeds of cpus I have access to
+#define hz (2400e6) glyme Core 2 "Conroe"
+#define hz (2000e6) jupiter G5
+#define hz (1592e6) titan
+#define hz (2793e6) athena/gaia
+#define hz (1250e6) isis G4
+#define hz (2160e6) imac Core 2 "Merom"
+#define hz (266e6) ppc/arm
+#define hz (400e6) mips
+*/
+
+/* --------------------------------------------------------------------------
+ * This implementation uses uint32_t and uint64_t as names for unsigned 32-
+ * and 64-bit integer types. These are defined in C99 stdint.h. The
+ * following may need adaptation if you are not running a C99 or
+ * Microsoft C environment.
+ * ----------------------------------------------------------------------- */
+#define VMAC_USE_STDINT 1 /* Set to zero if system has no stdint.h */
+
+#if VMAC_USE_STDINT && !_MSC_VER /* Try stdint.h if non-Microsoft */
+//#include <stdint.h>
+#elif (_MSC_VER) /* Microsoft C does not have stdint.h */
+typedef unsigned __int32 uint32_t;
+typedef unsigned __int64 uint64_t;
+#define UINT64_C(v) v ## UI64
+#else /* Guess sensibly - may need adaptation */
+typedef unsigned int uint32_t;
+typedef unsigned long long uint64_t;
+#define UINT64_C(v) v ## ULL
+#endif
+
+/* --------------------------------------------------------------------------
+ * This implementation supports two free AES implementations: OpenSSL's and
+ * Paulo Barreto's. To use OpenSSL's, you will need to include the OpenSSL
+ * crypto library (eg, gcc -lcrypto foo.c). For Barreto's, you will need
+ * to compile rijndael-alg-fst.c, last seen at http://www.iaik.tu-graz.ac.at/
+ * research/krypto/AES/old/~rijmen/rijndael/rijndael-fst-3.0.zip and
+ * http://homes.esat.kuleuven.be/~rijmen/rijndael/rijndael-fst-3.0.zip.
+ * To use a different implementation, use these definitions as a model.
+ * ----------------------------------------------------------------------- */
+#if VMAC_USE_OPENSSL
+
+#include <openssl/aes.h>
+typedef AES_KEY aes_int_key;
+
+#define aes_encryption(in,out,int_key) \
+ AES_encrypt((unsigned char *)(in),(unsigned char *)(out),(int_key))
+#define aes_key_setup(key,int_key) \
+ AES_set_encrypt_key((key),VMAC_KEY_LEN,(int_key))
+
+#else
+
+//#include "rijndael-alg-fst.h"
+typedef uint64_t vmac_t;
+#include "rijndael.h"
+typedef u32 aes_int_key[4*(VMAC_KEY_LEN/32+7)];
+
+#define aes_encryption(in,out,int_key) \
+ rijndaelEncrypt((u32 *)(int_key), \
+ ((VMAC_KEY_LEN/32)+6), \
+ (u8 *)(in), (u8 *)(out))
+#define aes_key_setup(user_key,int_key) \
+ rijndaelKeySetupEnc((u32 *)(int_key), \
+ (u8 *)(user_key), \
+ VMAC_KEY_LEN)
+#endif
+
+/* --------------------------------------------------------------------- */
+
+typedef struct {
+ uint64_t nhkey [(VMAC_NHBYTES/8)+2*(VMAC_TAG_LEN/64-1)];
+ uint64_t polykey[2*VMAC_TAG_LEN/64];
+ uint64_t l3key [2*VMAC_TAG_LEN/64];
+ uint64_t polytmp[2*VMAC_TAG_LEN/64];
+ aes_int_key cipher_key;
+ #if (VMAC_TAG_LEN == 64) && (VMAC_CACHE_NONCES)
+ uint64_t cached_nonce[2];
+ uint64_t cached_aes[2];
+ #endif
+ int first_block_processed;
+} vmac_ctx_t;
+
+/* --------------------------------------------------------------------- */
+/* --------------------------------------------------------------------------
+ * <<<<< USAGE NOTES >>>>>
+ *
+ * Given msg m (mbytes in length) and nonce buffer n
+ * this function returns a tag as its output. The tag is returned as
+ * a number. When VMAC_TAG_LEN == 64, the 'return'ed integer is the tag,
+ * and *tagl is meaningless. When VMAC_TAG_LEN == 128 the tag is the
+ * number y * 2^64 + *tagl where y is the function's return value.
+ * If you want to consider tags to be strings, then you must do so with
+ * an agreed upon endian orientation for interoperability, and convert
+ * the results appropriately. VHASH hashes m without creating any tag.
+ * Consecutive substrings forming a prefix of a message may be passed
+ * to vhash_update, with vhash or vmac being called with the remainder
+ * to produce the output.
+ *
+ * Requirements:
+ * - On 32-bit architectures with SSE2 instructions, ctx and m MUST be
+ * begin on 16-byte memory boundaries.
+ * - m MUST be your message followed by zeroes to the nearest 16-byte
+ * boundary. If m is a length multiple of 16 bytes, then it is already
+ * at a 16-byte boundary and needs no padding. mbytes should be your
+ * message length without any padding.
+ * - The first bit of the nonce buffer n must be 0. An i byte nonce, is made
+ * as the first 16-i bytes of n being zero, and the final i the nonce.
+ * - vhash_update MUST have mbytes be a positive multiple of VMAC_NHBYTES
+ * ----------------------------------------------------------------------- */
+
+#define vmac_update vhash_update
+
+void vhash_update(unsigned char m[],
+ unsigned int mbytes,
+ vmac_ctx_t *ctx);
+
+uint64_t vmac(unsigned char m[],
+ unsigned int mbytes,
+ unsigned char n[16],
+ uint64_t *tagl,
+ vmac_ctx_t *ctx);
+
+uint64_t vhash(unsigned char m[],
+ unsigned int mbytes,
+ uint64_t *tagl,
+ vmac_ctx_t *ctx);
+
+/* --------------------------------------------------------------------------
+ * When passed a VMAC_KEY_LEN bit user_key, this function initialazies ctx.
+ * ----------------------------------------------------------------------- */
+
+void vmac_set_key(unsigned char user_key[], vmac_ctx_t *ctx);
+
+/* --------------------------------------------------------------------------
+ * This function aborts current hash and resets ctx, ready for a new message.
+ * ----------------------------------------------------------------------- */
+
+void vhash_abort(vmac_ctx_t *ctx);
+
+/* --------------------------------------------------------------------- */
+
+#endif /* HEADER_AES_H */