1/* LibTomCrypt, modular cryptographic library -- Tom St Denis
2 *
3 * LibTomCrypt is a library that provides various cryptographic
4 * algorithms in a highly modular and flexible manner.
5 *
6 * The library is free for all purposes without any express
7 * guarantee it works.
8 *
9 * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com
10 */
11#include "tomcrypt.h"
12
13/**
14  @file omac_init.c
15  OMAC1 support, initialize state, by Tom St Denis
16*/
17
18
19#ifdef LTC_OMAC
20
21/**
22   Initialize an OMAC state
23   @param omac    The OMAC state to initialize
24   @param cipher  The index of the desired cipher
25   @param key     The secret key
26   @param keylen  The length of the secret key (octets)
27   @return CRYPT_OK if successful
28*/
29int omac_init(omac_state *omac, int cipher, const unsigned char *key, unsigned long keylen)
30{
31   int err, x, y, mask, msb, len;
32
33   LTC_ARGCHK(omac != NULL);
34   LTC_ARGCHK(key  != NULL);
35
36   /* schedule the key */
37   if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
38      return err;
39   }
40
41#ifdef LTC_FAST
42   if (cipher_descriptor[cipher].block_length % sizeof(LTC_FAST_TYPE)) {
43       return CRYPT_INVALID_ARG;
44   }
45#endif
46
47   /* now setup the system */
48   switch (cipher_descriptor[cipher].block_length) {
49       case 8:  mask = 0x1B;
50                len  = 8;
51                break;
52       case 16: mask = 0x87;
53                len  = 16;
54                break;
55       default: return CRYPT_INVALID_ARG;
56   }
57
58   if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &omac->key)) != CRYPT_OK) {
59      return err;
60   }
61
62   /* ok now we need Lu and Lu^2 [calc one from the other] */
63
64   /* first calc L which is Ek(0) */
65   zeromem(omac->Lu[0], cipher_descriptor[cipher].block_length);
66   if ((err = cipher_descriptor[cipher].ecb_encrypt(omac->Lu[0], omac->Lu[0], &omac->key)) != CRYPT_OK) {
67      return err;
68   }
69
70   /* now do the mults, whoopy! */
71   for (x = 0; x < 2; x++) {
72       /* if msb(L * u^(x+1)) = 0 then just shift, otherwise shift and xor constant mask */
73       msb = omac->Lu[x][0] >> 7;
74
75       /* shift left */
76       for (y = 0; y < (len - 1); y++) {
77           omac->Lu[x][y] = ((omac->Lu[x][y] << 1) | (omac->Lu[x][y+1] >> 7)) & 255;
78       }
79       omac->Lu[x][len - 1] = ((omac->Lu[x][len - 1] << 1) ^ (msb ? mask : 0)) & 255;
80
81       /* copy up as require */
82       if (x == 0) {
83          XMEMCPY(omac->Lu[1], omac->Lu[0], sizeof(omac->Lu[0]));
84       }
85   }
86
87   /* setup state */
88   omac->cipher_idx = cipher;
89   omac->buflen     = 0;
90   omac->blklen     = len;
91   zeromem(omac->prev,  sizeof(omac->prev));
92   zeromem(omac->block, sizeof(omac->block));
93
94   return CRYPT_OK;
95}
96
97#endif
98
99/* $Source: /cvs/libtom/libtomcrypt/src/mac/omac/omac_init.c,v $ */
100/* $Revision: 1.10 $ */
101/* $Date: 2006/11/03 00:39:49 $ */
102