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