Line data Source code
1 : /* siv-cmac.c
2 :
3 : SIV-CMAC, RFC5297
4 :
5 : Copyright (C) 2017 Nikos Mavrogiannopoulos
6 :
7 : This file is part of GNU Nettle.
8 :
9 : GNU Nettle is free software: you can redistribute it and/or
10 : modify it under the terms of either:
11 :
12 : * the GNU Lesser General Public License as published by the Free
13 : Software Foundation; either version 3 of the License, or (at your
14 : option) any later version.
15 :
16 : or
17 :
18 : * the GNU General Public License as published by the Free
19 : Software Foundation; either version 2 of the License, or (at your
20 : option) any later version.
21 :
22 : or both in parallel, as here.
23 :
24 : GNU Nettle is distributed in the hope that it will be useful,
25 : but WITHOUT ANY WARRANTY; without even the implied warranty of
26 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
27 : General Public License for more details.
28 :
29 : You should have received copies of the GNU General Public License and
30 : the GNU Lesser General Public License along with this program. If
31 : not, see http://www.gnu.org/licenses/.
32 : */
33 :
34 : #if HAVE_CONFIG_H
35 : #include "config.h"
36 : #endif
37 :
38 : #include <assert.h>
39 : #include <string.h>
40 :
41 : #include <nettle/aes.h>
42 : #include "siv-cmac.h"
43 : #ifdef HAVE_NETTLE_CMAC128_UPDATE
44 : #include <nettle/cmac.h>
45 : #else
46 : #include "cmac.h"
47 : #endif
48 : #include <nettle/ctr.h>
49 : #include <nettle/memxor.h>
50 : #include <nettle/memops.h>
51 : #include "nettle-alloca.h"
52 : #include "block-internal.h"
53 :
54 : /* This is an implementation of S2V for the AEAD case where
55 : * vectors if zero, are considered as S empty components */
56 : static void
57 50 : _siv_s2v (const struct nettle_cipher *nc,
58 : const struct cmac128_key *cmac_key,
59 : const void *cmac_cipher,
60 : size_t alength, const uint8_t * adata,
61 : size_t nlength, const uint8_t * nonce,
62 : size_t plength, const uint8_t * pdata, uint8_t * v)
63 : {
64 50 : union nettle_block16 D, S, T;
65 50 : static const union nettle_block16 const_zero = {.b = 0 };
66 50 : struct cmac128_ctx cmac_ctx;
67 50 : assert (nlength >= SIV_MIN_NONCE_SIZE);
68 :
69 50 : cmac128_init(&cmac_ctx);
70 50 : cmac128_update (&cmac_ctx, cmac_cipher, nc->encrypt, 16, const_zero.b);
71 50 : cmac128_digest (&cmac_ctx, cmac_key, cmac_cipher, nc->encrypt, 16, D.b);
72 :
73 50 : block16_mulx_be (&D, &D);
74 50 : cmac128_update (&cmac_ctx, cmac_cipher, nc->encrypt, alength, adata);
75 50 : cmac128_digest (&cmac_ctx, cmac_key, cmac_cipher, nc->encrypt, 16, S.b);
76 50 : block16_xor (&D, &S);
77 :
78 50 : block16_mulx_be (&D, &D);
79 50 : cmac128_update (&cmac_ctx, cmac_cipher, nc->encrypt, nlength, nonce);
80 50 : cmac128_digest (&cmac_ctx, cmac_key, cmac_cipher, nc->encrypt, 16, S.b);
81 50 : block16_xor (&D, &S);
82 :
83 : /* Sn */
84 50 : if (plength >= 16)
85 : {
86 50 : cmac128_update (&cmac_ctx, cmac_cipher, nc->encrypt, plength - 16, pdata);
87 :
88 50 : pdata += plength - 16;
89 :
90 50 : block16_xor_bytes (&T, &D, pdata);
91 : }
92 : else
93 : {
94 0 : union nettle_block16 pad;
95 :
96 0 : block16_mulx_be (&T, &D);
97 0 : memcpy (pad.b, pdata, plength);
98 0 : pad.b[plength] = 0x80;
99 0 : if (plength + 1 < 16)
100 0 : memset (&pad.b[plength + 1], 0, 16 - plength - 1);
101 :
102 0 : block16_xor (&T, &pad);
103 : }
104 :
105 50 : cmac128_update (&cmac_ctx, cmac_cipher, nc->encrypt, 16, T.b);
106 50 : cmac128_digest (&cmac_ctx, cmac_key, cmac_cipher, nc->encrypt, 16, v);
107 50 : }
108 :
109 : void
110 20 : siv_cmac_set_key (struct cmac128_key *cmac_key, void *cmac_cipher, void *siv_cipher,
111 : const struct nettle_cipher *nc, const uint8_t * key)
112 : {
113 20 : nc->set_encrypt_key (cmac_cipher, key);
114 20 : cmac128_set_key (cmac_key, cmac_cipher, nc->encrypt);
115 20 : nc->set_encrypt_key (siv_cipher, key + nc->key_size);
116 20 : }
117 :
118 : void
119 30 : siv_cmac_encrypt_message (const struct cmac128_key *cmac_key,
120 : const void *cmac_cipher,
121 : const struct nettle_cipher *nc,
122 : const void *ctr_cipher,
123 : size_t nlength, const uint8_t * nonce,
124 : size_t alength, const uint8_t * adata,
125 : size_t clength, uint8_t * dst, const uint8_t * src)
126 : {
127 30 : union nettle_block16 siv;
128 30 : size_t slength;
129 :
130 30 : assert (clength >= SIV_DIGEST_SIZE);
131 30 : slength = clength - SIV_DIGEST_SIZE;
132 :
133 : /* create CTR nonce */
134 30 : _siv_s2v (nc, cmac_key, cmac_cipher, alength, adata, nlength, nonce, slength, src, siv.b);
135 :
136 30 : memcpy (dst, siv.b, SIV_DIGEST_SIZE);
137 30 : siv.b[8] &= ~0x80;
138 30 : siv.b[12] &= ~0x80;
139 :
140 30 : ctr_crypt (ctr_cipher, nc->encrypt, AES_BLOCK_SIZE, siv.b, slength,
141 : dst + SIV_DIGEST_SIZE, src);
142 30 : }
143 :
144 : int
145 20 : siv_cmac_decrypt_message (const struct cmac128_key *cmac_key,
146 : const void *cmac_cipher,
147 : const struct nettle_cipher *nc,
148 : const void *ctr_cipher,
149 : size_t nlength, const uint8_t * nonce,
150 : size_t alength, const uint8_t * adata,
151 : size_t mlength, uint8_t * dst, const uint8_t * src)
152 : {
153 20 : union nettle_block16 siv;
154 20 : union nettle_block16 ctr;
155 :
156 20 : memcpy (ctr.b, src, SIV_DIGEST_SIZE);
157 20 : ctr.b[8] &= ~0x80;
158 20 : ctr.b[12] &= ~0x80;
159 :
160 20 : ctr_crypt (ctr_cipher, nc->encrypt, AES_BLOCK_SIZE, ctr.b,
161 : mlength, dst, src + SIV_DIGEST_SIZE);
162 :
163 : /* create CTR nonce */
164 20 : _siv_s2v (nc,
165 : cmac_key, cmac_cipher, alength, adata,
166 : nlength, nonce, mlength, dst, siv.b);
167 :
168 20 : return memeql_sec (siv.b, src, SIV_DIGEST_SIZE);
169 : }
|