Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/opencrypto/gmac.c
39475 views
1
/*-
2
* Copyright (c) 2014 The FreeBSD Foundation
3
*
4
* This software was developed by John-Mark Gurney under
5
* the sponsorship of the FreeBSD Foundation and
6
* Rubicon Communications, LLC (Netgate).
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted provided that the following conditions
9
* are met:
10
* 1. Redistributions of source code must retain the above copyright
11
* notice, this list of conditions and the following disclaimer.
12
* 2. Redistributions in binary form must reproduce the above copyright
13
* notice, this list of conditions and the following disclaimer in the
14
* documentation and/or other materials provided with the distribution.
15
*
16
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26
* SUCH DAMAGE.
27
*
28
*/
29
30
#include <sys/types.h>
31
#include <sys/systm.h>
32
#include <opencrypto/gfmult.h>
33
#include <opencrypto/gmac.h>
34
35
void
36
AES_GMAC_Init(void *ctx)
37
{
38
struct aes_gmac_ctx *agc;
39
40
agc = ctx;
41
bzero(agc, sizeof *agc);
42
}
43
44
void
45
AES_GMAC_Setkey(void *ctx, const uint8_t *key, u_int klen)
46
{
47
struct aes_gmac_ctx *agc;
48
const uint8_t zeros[GMAC_BLOCK_LEN] = {};
49
struct gf128 h;
50
uint8_t hbuf[GMAC_BLOCK_LEN];
51
52
agc = ctx;
53
agc->rounds = rijndaelKeySetupEnc(agc->keysched, key, klen * 8);
54
55
rijndaelEncrypt(agc->keysched, agc->rounds, zeros, hbuf);
56
57
h = gf128_read(hbuf);
58
gf128_genmultable4(h, &agc->ghashtbl);
59
60
explicit_bzero(&h, sizeof h);
61
explicit_bzero(hbuf, sizeof hbuf);
62
}
63
64
void
65
AES_GMAC_Reinit(void *ctx, const uint8_t *iv, u_int ivlen)
66
{
67
struct aes_gmac_ctx *agc;
68
69
agc = ctx;
70
KASSERT(ivlen <= sizeof agc->counter, ("passed ivlen too large!"));
71
memset(agc->counter, 0, sizeof(agc->counter));
72
bcopy(iv, agc->counter, ivlen);
73
agc->counter[GMAC_BLOCK_LEN - 1] = 1;
74
75
memset(&agc->hash, 0, sizeof(agc->hash));
76
}
77
78
int
79
AES_GMAC_Update(void *ctx, const void *vdata, u_int len)
80
{
81
struct aes_gmac_ctx *agc;
82
const uint8_t *data;
83
struct gf128 v;
84
uint8_t buf[GMAC_BLOCK_LEN] = {};
85
int i;
86
87
agc = ctx;
88
data = vdata;
89
v = agc->hash;
90
91
while (len > 0) {
92
if (len >= 4*GMAC_BLOCK_LEN) {
93
i = 4*GMAC_BLOCK_LEN;
94
v = gf128_mul4b(v, data, &agc->ghashtbl);
95
} else if (len >= GMAC_BLOCK_LEN) {
96
i = GMAC_BLOCK_LEN;
97
v = gf128_add(v, gf128_read(data));
98
v = gf128_mul(v, &agc->ghashtbl.tbls[0]);
99
} else {
100
i = len;
101
bcopy(data, buf, i);
102
v = gf128_add(v, gf128_read(&buf[0]));
103
v = gf128_mul(v, &agc->ghashtbl.tbls[0]);
104
explicit_bzero(buf, sizeof buf);
105
}
106
len -= i;
107
data += i;
108
}
109
110
agc->hash = v;
111
explicit_bzero(&v, sizeof v);
112
113
return (0);
114
}
115
116
void
117
AES_GMAC_Final(uint8_t *digest, void *ctx)
118
{
119
struct aes_gmac_ctx *agc;
120
uint8_t enccntr[GMAC_BLOCK_LEN];
121
struct gf128 a;
122
123
agc = ctx;
124
125
rijndaelEncrypt(agc->keysched, agc->rounds, agc->counter, enccntr);
126
a = gf128_add(agc->hash, gf128_read(enccntr));
127
gf128_write(a, digest);
128
129
explicit_bzero(enccntr, sizeof enccntr);
130
}
131
132