aes-omac1.c
Go to the documentation of this file.
00001 /*
00002  * One-key CBC MAC (OMAC1) hash with AES-128
00003  *
00004  * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License version 2 as
00008  * published by the Free Software Foundation.
00009  *
00010  * Alternatively, this software may be distributed under the terms of BSD
00011  * license.
00012  *
00013  * See README and COPYING for more details.
00014  */
00015 
00016 #include "includes.h"
00017 
00018 #include "common.h"
00019 #include "aes.h"
00020 #include "aes_wrap.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 
00048 int omac1_aes_128_vector(const u8 *key, size_t num_elem,
00049                          const u8 *addr[], const size_t *len, u8 *mac)
00050 {
00051         void *ctx;
00052         u8 cbc[AES_BLOCK_SIZE], pad[AES_BLOCK_SIZE];
00053         const u8 *pos, *end;
00054         size_t i, e, left, total_len;
00055 
00056         ctx = aes_encrypt_init(key, 16);
00057         if (ctx == NULL)
00058                 return -1;
00059         os_memset(cbc, 0, AES_BLOCK_SIZE);
00060 
00061         total_len = 0;
00062         for (e = 0; e < num_elem; e++)
00063                 total_len += len[e];
00064         left = total_len;
00065 
00066         e = 0;
00067         pos = addr[0];
00068         end = pos + len[0];
00069 
00070         while (left >= AES_BLOCK_SIZE) {
00071                 for (i = 0; i < AES_BLOCK_SIZE; i++) {
00072                         cbc[i] ^= *pos++;
00073                         if (pos >= end) {
00074                                 e++;
00075                                 pos = addr[e];
00076                                 end = pos + len[e];
00077                         }
00078                 }
00079                 if (left > AES_BLOCK_SIZE)
00080                         aes_encrypt(ctx, cbc, cbc);
00081                 left -= AES_BLOCK_SIZE;
00082         }
00083 
00084         os_memset(pad, 0, AES_BLOCK_SIZE);
00085         aes_encrypt(ctx, pad, pad);
00086         gf_mulx(pad);
00087 
00088         if (left || total_len == 0) {
00089                 for (i = 0; i < left; i++) {
00090                         cbc[i] ^= *pos++;
00091                         if (pos >= end) {
00092                                 e++;
00093                                 pos = addr[e];
00094                                 end = pos + len[e];
00095                         }
00096                 }
00097                 cbc[left] ^= 0x80;
00098                 gf_mulx(pad);
00099         }
00100 
00101         for (i = 0; i < AES_BLOCK_SIZE; i++)
00102                 pad[i] ^= cbc[i];
00103         aes_encrypt(ctx, pad, mac);
00104         aes_encrypt_deinit(ctx);
00105         return 0;
00106 }
00107 
00108 
00121 int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
00122 {
00123         return omac1_aes_128_vector(key, 1, &data, &data_len, mac);
00124 }


wpa_supplicant_node
Author(s): Package maintained by Blaise Gassend
autogenerated on Thu Apr 24 2014 15:33:19