4
/* --------------------------------------------------------------------------
5
* VMAC and VHASH Implementation by Ted Krovetz (tdk@acm.org) and Wei Dai.
6
* This implementation is herby placed in the public domain.
7
* The authors offers no warranty. Use at your own risk.
8
* Please send bug reports to the authors.
9
* Last modified: 17 APR 08, 1700 PDT
10
* ----------------------------------------------------------------------- */
12
/* --------------------------------------------------------------------------
13
* User definable settings.
14
* ----------------------------------------------------------------------- */
15
#define VMAC_TAG_LEN 64 /* Must be 64 or 128 - 64 sufficient for most */
16
#define VMAC_KEY_LEN 128 /* Must be 128, 192 or 256 */
17
#define VMAC_NHBYTES 128 /* Must 2^i for any 3 < i < 13. Standard = 128 */
18
#define VMAC_PREFER_BIG_ENDIAN 0 /* Prefer non-x86 */
20
#define VMAC_USE_OPENSSL 0 /* Set to non-zero to use OpenSSL's AES */
21
#define VMAC_CACHE_NONCES 1 /* Set to non-zero to cause caching */
22
/* of consecutive nonces on 64-bit tags */
24
#define VMAC_RUN_TESTS 0 /* Set to non-zero to check vectors and speed */
25
#define VMAC_HZ (448e6) /* Set to hz of host machine to get speed */
26
#define VMAC_HASH_ONLY 0 /* Set to non-zero to time hash only (not-mac) */
27
/* Speeds of cpus I have access to
28
#define hz (2400e6) glyme Core 2 "Conroe"
29
#define hz (2000e6) jupiter G5
30
#define hz (1592e6) titan
31
#define hz (2793e6) athena/gaia
32
#define hz (1250e6) isis G4
33
#define hz (2160e6) imac Core 2 "Merom"
34
#define hz (266e6) ppc/arm
35
#define hz (400e6) mips
38
/* --------------------------------------------------------------------------
39
* This implementation uses uint32_t and uint64_t as names for unsigned 32-
40
* and 64-bit integer types. These are defined in C99 stdint.h. The
41
* following may need adaptation if you are not running a C99 or
42
* Microsoft C environment.
43
* ----------------------------------------------------------------------- */
44
#define VMAC_USE_STDINT 1 /* Set to zero if system has no stdint.h */
46
#if VMAC_USE_STDINT && !_MSC_VER /* Try stdint.h if non-Microsoft */
48
#define __STDC_CONSTANT_MACROS
51
#elif (_MSC_VER) /* Microsoft C does not have stdint.h */
52
typedef unsigned __int32 uint32_t;
53
typedef unsigned __int64 uint64_t;
54
#define UINT64_C(v) v ## UI64
55
#else /* Guess sensibly - may need adaptation */
56
typedef unsigned int uint32_t;
57
typedef unsigned long long uint64_t;
58
#define UINT64_C(v) v ## ULL
61
/* --------------------------------------------------------------------------
62
* This implementation supports two free AES implementations: OpenSSL's and
63
* Paulo Barreto's. To use OpenSSL's, you will need to include the OpenSSL
64
* crypto library (eg, gcc -lcrypto foo.c). For Barreto's, you will need
65
* to compile rijndael-alg-fst.c, last seen at http://www.iaik.tu-graz.ac.at/
66
* research/krypto/AES/old/~rijmen/rijndael/rijndael-fst-3.0.zip and
67
* http://homes.esat.kuleuven.be/~rijmen/rijndael/rijndael-fst-3.0.zip.
68
* To use a different implementation, use these definitions as a model.
69
* ----------------------------------------------------------------------- */
72
#include <openssl/aes.h>
73
typedef AES_KEY aes_int_key;
75
#define aes_encryption(in,out,int_key) \
76
AES_encrypt((unsigned char *)(in),(unsigned char *)(out),(int_key))
77
#define aes_key_setup(key,int_key) \
78
AES_set_encrypt_key((key),VMAC_KEY_LEN,(int_key))
82
//#include "rijndael-alg-fst.h"
83
typedef uint64_t vmac_t;
85
typedef u32 aes_int_key[4*(VMAC_KEY_LEN/32+7)];
87
#define aes_encryption(in,out,int_key) \
88
rijndaelEncrypt((u32 *)(int_key), \
89
((VMAC_KEY_LEN/32)+6), \
90
(u8 *)(in), (u8 *)(out))
91
#define aes_key_setup(user_key,int_key) \
92
rijndaelKeySetupEnc((u32 *)(int_key), \
97
/* --------------------------------------------------------------------- */
100
uint64_t nhkey [(VMAC_NHBYTES/8)+2*(VMAC_TAG_LEN/64-1)];
101
uint64_t polykey[2*VMAC_TAG_LEN/64];
102
uint64_t l3key [2*VMAC_TAG_LEN/64];
103
uint64_t polytmp[2*VMAC_TAG_LEN/64];
104
aes_int_key cipher_key;
105
#if (VMAC_TAG_LEN == 64) && (VMAC_CACHE_NONCES)
106
uint64_t cached_nonce[2];
107
uint64_t cached_aes[2];
109
int first_block_processed;
112
/* --------------------------------------------------------------------- */
116
/* --------------------------------------------------------------------------
117
* <<<<< USAGE NOTES >>>>>
119
* Given msg m (mbytes in length) and nonce buffer n
120
* this function returns a tag as its output. The tag is returned as
121
* a number. When VMAC_TAG_LEN == 64, the 'return'ed integer is the tag,
122
* and *tagl is meaningless. When VMAC_TAG_LEN == 128 the tag is the
123
* number y * 2^64 + *tagl where y is the function's return value.
124
* If you want to consider tags to be strings, then you must do so with
125
* an agreed upon endian orientation for interoperability, and convert
126
* the results appropriately. VHASH hashes m without creating any tag.
127
* Consecutive substrings forming a prefix of a message may be passed
128
* to vhash_update, with vhash or vmac being called with the remainder
129
* to produce the output.
132
* - On 32-bit architectures with SSE2 instructions, ctx and m MUST be
133
* begin on 16-byte memory boundaries.
134
* - m MUST be your message followed by zeroes to the nearest 16-byte
135
* boundary. If m is a length multiple of 16 bytes, then it is already
136
* at a 16-byte boundary and needs no padding. mbytes should be your
137
* message length without any padding.
138
* - The first bit of the nonce buffer n must be 0. An i byte nonce, is made
139
* as the first 16-i bytes of n being zero, and the final i the nonce.
140
* - vhash_update MUST have mbytes be a positive multiple of VMAC_NHBYTES
141
* ----------------------------------------------------------------------- */
143
#define vmac_update vhash_update
145
void vhash_update(unsigned char m[],
149
uint64_t vmac(unsigned char m[],
155
uint64_t vhash(unsigned char m[],
160
/* --------------------------------------------------------------------------
161
* When passed a VMAC_KEY_LEN bit user_key, this function initialazies ctx.
162
* ----------------------------------------------------------------------- */
164
void vmac_set_key(unsigned char user_key[], vmac_ctx_t *ctx);
166
/* --------------------------------------------------------------------------
167
* This function aborts current hash and resets ctx, ready for a new message.
168
* ----------------------------------------------------------------------- */
170
void vhash_abort(vmac_ctx_t *ctx);
172
/* --------------------------------------------------------------------- */
178
#endif /* HEADER_AES_H */