Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/tomcrypt/src/mac/pmac/pmac_init.c
8525 views
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
#include "tomcrypt.h"
10
11
/**
12
@file pmac_init.c
13
PMAC implementation, initialize state, by Tom St Denis
14
*/
15
16
#ifdef LTC_PMAC
17
18
static const struct {
19
int len;
20
unsigned char poly_div[MAXBLOCKSIZE],
21
poly_mul[MAXBLOCKSIZE];
22
} polys[] = {
23
{
24
8,
25
{ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D },
26
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B }
27
}, {
28
16,
29
{ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
30
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43 },
31
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
32
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87 }
33
}
34
};
35
36
/**
37
Initialize a PMAC state
38
@param pmac The PMAC state to initialize
39
@param cipher The index of the desired cipher
40
@param key The secret key
41
@param keylen The length of the secret key (octets)
42
@return CRYPT_OK if successful
43
*/
44
int pmac_init(pmac_state *pmac, int cipher, const unsigned char *key, unsigned long keylen)
45
{
46
int poly, x, y, m, err;
47
unsigned char *L;
48
49
LTC_ARGCHK(pmac != NULL);
50
LTC_ARGCHK(key != NULL);
51
52
/* valid cipher? */
53
if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
54
return err;
55
}
56
57
/* determine which polys to use */
58
pmac->block_len = cipher_descriptor[cipher].block_length;
59
for (poly = 0; poly < (int)(sizeof(polys)/sizeof(polys[0])); poly++) {
60
if (polys[poly].len == pmac->block_len) {
61
break;
62
}
63
}
64
if (poly >= (int)(sizeof(polys)/sizeof(polys[0]))) {
65
return CRYPT_INVALID_ARG;
66
}
67
if (polys[poly].len != pmac->block_len) {
68
return CRYPT_INVALID_ARG;
69
}
70
71
#ifdef LTC_FAST
72
if (pmac->block_len % sizeof(LTC_FAST_TYPE)) {
73
return CRYPT_INVALID_ARG;
74
}
75
#endif
76
77
78
/* schedule the key */
79
if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &pmac->key)) != CRYPT_OK) {
80
return err;
81
}
82
83
/* allocate L */
84
L = XMALLOC(pmac->block_len);
85
if (L == NULL) {
86
return CRYPT_MEM;
87
}
88
89
/* find L = E[0] */
90
zeromem(L, pmac->block_len);
91
if ((err = cipher_descriptor[cipher].ecb_encrypt(L, L, &pmac->key)) != CRYPT_OK) {
92
goto error;
93
}
94
95
/* find Ls[i] = L << i for i == 0..31 */
96
XMEMCPY(pmac->Ls[0], L, pmac->block_len);
97
for (x = 1; x < 32; x++) {
98
m = pmac->Ls[x-1][0] >> 7;
99
for (y = 0; y < pmac->block_len-1; y++) {
100
pmac->Ls[x][y] = ((pmac->Ls[x-1][y] << 1) | (pmac->Ls[x-1][y+1] >> 7)) & 255;
101
}
102
pmac->Ls[x][pmac->block_len-1] = (pmac->Ls[x-1][pmac->block_len-1] << 1) & 255;
103
104
if (m == 1) {
105
for (y = 0; y < pmac->block_len; y++) {
106
pmac->Ls[x][y] ^= polys[poly].poly_mul[y];
107
}
108
}
109
}
110
111
/* find Lr = L / x */
112
m = L[pmac->block_len-1] & 1;
113
114
/* shift right */
115
for (x = pmac->block_len - 1; x > 0; x--) {
116
pmac->Lr[x] = ((L[x] >> 1) | (L[x-1] << 7)) & 255;
117
}
118
pmac->Lr[0] = L[0] >> 1;
119
120
if (m == 1) {
121
for (x = 0; x < pmac->block_len; x++) {
122
pmac->Lr[x] ^= polys[poly].poly_div[x];
123
}
124
}
125
126
/* zero buffer, counters, etc... */
127
pmac->block_index = 1;
128
pmac->cipher_idx = cipher;
129
pmac->buflen = 0;
130
zeromem(pmac->block, sizeof(pmac->block));
131
zeromem(pmac->Li, sizeof(pmac->Li));
132
zeromem(pmac->checksum, sizeof(pmac->checksum));
133
err = CRYPT_OK;
134
error:
135
#ifdef LTC_CLEAN_STACK
136
zeromem(L, pmac->block_len);
137
#endif
138
139
XFREE(L);
140
141
return err;
142
}
143
144
#endif
145
146