aes-omac1.c
Go to the documentation of this file.00001
00017 #include "includes.h"
00018
00019 #include "common.h"
00020 #include "aes.h"
00021
00022 static void gf_mulx(u8 *pad)
00023 {
00024 int i, carry;
00025
00026 carry = pad[0] & 0x80;
00027 for (i = 0; i < AES_BLOCK_SIZE - 1; i++)
00028 pad[i] = (pad[i] << 1) | (pad[i + 1] >> 7);
00029 pad[AES_BLOCK_SIZE - 1] <<= 1;
00030 if (carry)
00031 pad[AES_BLOCK_SIZE - 1] ^= 0x87;
00032 }
00033
00034
00049 int omac1_aes_128_vector(const u8 *key, size_t num_elem,
00050 const u8 *addr[], const size_t *len, u8 *mac)
00051 {
00052 void *ctx;
00053 u8 cbc[AES_BLOCK_SIZE], pad[AES_BLOCK_SIZE];
00054 const u8 *pos, *end;
00055 size_t i, e, left, total_len;
00056
00057 ctx = aes_encrypt_init(key, 16);
00058 if (ctx == NULL)
00059 return -1;
00060 os_memset(cbc, 0, AES_BLOCK_SIZE);
00061
00062 total_len = 0;
00063 for (e = 0; e < num_elem; e++)
00064 total_len += len[e];
00065 left = total_len;
00066
00067 e = 0;
00068 pos = addr[0];
00069 end = pos + len[0];
00070
00071 while (left >= AES_BLOCK_SIZE) {
00072 for (i = 0; i < AES_BLOCK_SIZE; i++) {
00073 cbc[i] ^= *pos++;
00074 if (pos >= end) {
00075 e++;
00076 pos = addr[e];
00077 end = pos + len[e];
00078 }
00079 }
00080 if (left > AES_BLOCK_SIZE)
00081 aes_encrypt(ctx, cbc, cbc);
00082 left -= AES_BLOCK_SIZE;
00083 }
00084
00085 os_memset(pad, 0, AES_BLOCK_SIZE);
00086 aes_encrypt(ctx, pad, pad);
00087 gf_mulx(pad);
00088
00089 if (left || total_len == 0) {
00090 for (i = 0; i < left; i++) {
00091 cbc[i] ^= *pos++;
00092 if (pos >= end) {
00093 e++;
00094 pos = addr[e];
00095 end = pos + len[e];
00096 }
00097 }
00098 cbc[left] ^= 0x80;
00099 gf_mulx(pad);
00100 }
00101
00102 for (i = 0; i < AES_BLOCK_SIZE; i++)
00103 pad[i] ^= cbc[i];
00104 aes_encrypt(ctx, pad, mac);
00105 aes_encrypt_deinit(ctx);
00106 return 0;
00107 }
00108
00109
00123 int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
00124 {
00125 return omac1_aes_128_vector(key, 1, &data, &data_len, mac);
00126 }
00127