Line | Count | Source (jump to first uncovered line) |
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 "aes.h" |
42 | | #include "siv-cmac.h" |
43 | | #include "cmac.h" |
44 | | #include "ctr.h" |
45 | | #include "memxor.h" |
46 | | #include "memops.h" |
47 | | #include "nettle-internal.h" |
48 | | #include "block-internal.h" |
49 | | |
50 | | /* This is an implementation of S2V for the AEAD case where |
51 | | * vectors if zero, are considered as S empty components */ |
52 | | static void |
53 | | _siv_s2v (const struct nettle_cipher *nc, |
54 | | const struct cmac128_key *cmac_key, |
55 | | const void *cmac_cipher, |
56 | | size_t alength, const uint8_t * adata, |
57 | | size_t nlength, const uint8_t * nonce, |
58 | | size_t plength, const uint8_t * pdata, uint8_t * v) |
59 | 0 | { |
60 | 0 | union nettle_block16 D, S, T; |
61 | 0 | static const union nettle_block16 const_zero = {.b = 0 }; |
62 | 0 | struct cmac128_ctx cmac_ctx; |
63 | 0 | assert (nlength >= SIV_MIN_NONCE_SIZE); |
64 | | |
65 | 0 | cmac128_init(&cmac_ctx); |
66 | 0 | cmac128_update (&cmac_ctx, cmac_cipher, nc->encrypt, 16, const_zero.b); |
67 | 0 | cmac128_digest (&cmac_ctx, cmac_key, cmac_cipher, nc->encrypt, 16, D.b); |
68 | |
|
69 | 0 | block16_mulx_be (&D, &D); |
70 | 0 | cmac128_update (&cmac_ctx, cmac_cipher, nc->encrypt, alength, adata); |
71 | 0 | cmac128_digest (&cmac_ctx, cmac_key, cmac_cipher, nc->encrypt, 16, S.b); |
72 | 0 | block16_xor (&D, &S); |
73 | |
|
74 | 0 | block16_mulx_be (&D, &D); |
75 | 0 | cmac128_update (&cmac_ctx, cmac_cipher, nc->encrypt, nlength, nonce); |
76 | 0 | cmac128_digest (&cmac_ctx, cmac_key, cmac_cipher, nc->encrypt, 16, S.b); |
77 | 0 | block16_xor (&D, &S); |
78 | | |
79 | | /* Sn */ |
80 | 0 | if (plength >= 16) |
81 | 0 | { |
82 | 0 | cmac128_update (&cmac_ctx, cmac_cipher, nc->encrypt, plength - 16, pdata); |
83 | |
|
84 | 0 | pdata += plength - 16; |
85 | |
|
86 | 0 | block16_xor_bytes (&T, &D, pdata); |
87 | 0 | } |
88 | 0 | else |
89 | 0 | { |
90 | 0 | union nettle_block16 pad; |
91 | |
|
92 | 0 | block16_mulx_be (&T, &D); |
93 | 0 | memcpy (pad.b, pdata, plength); |
94 | 0 | pad.b[plength] = 0x80; |
95 | 0 | if (plength + 1 < 16) |
96 | 0 | memset (&pad.b[plength + 1], 0, 16 - plength - 1); |
97 | |
|
98 | 0 | block16_xor (&T, &pad); |
99 | 0 | } |
100 | |
|
101 | 0 | cmac128_update (&cmac_ctx, cmac_cipher, nc->encrypt, 16, T.b); |
102 | 0 | cmac128_digest (&cmac_ctx, cmac_key, cmac_cipher, nc->encrypt, 16, v); |
103 | 0 | } |
104 | | |
105 | | void |
106 | | siv_cmac_set_key (struct cmac128_key *cmac_key, void *cmac_cipher, void *siv_cipher, |
107 | | const struct nettle_cipher *nc, const uint8_t * key) |
108 | 0 | { |
109 | 0 | nc->set_encrypt_key (cmac_cipher, key); |
110 | 0 | cmac128_set_key (cmac_key, cmac_cipher, nc->encrypt); |
111 | 0 | nc->set_encrypt_key (siv_cipher, key + nc->key_size); |
112 | 0 | } |
113 | | |
114 | | void |
115 | | siv_cmac_encrypt_message (const struct cmac128_key *cmac_key, |
116 | | const void *cmac_cipher, |
117 | | const struct nettle_cipher *nc, |
118 | | const void *ctr_cipher, |
119 | | size_t nlength, const uint8_t * nonce, |
120 | | size_t alength, const uint8_t * adata, |
121 | | size_t clength, uint8_t * dst, const uint8_t * src) |
122 | 0 | { |
123 | 0 | union nettle_block16 siv; |
124 | 0 | size_t slength; |
125 | |
|
126 | 0 | assert (clength >= SIV_DIGEST_SIZE); |
127 | 0 | slength = clength - SIV_DIGEST_SIZE; |
128 | | |
129 | | /* create CTR nonce */ |
130 | 0 | _siv_s2v (nc, cmac_key, cmac_cipher, alength, adata, nlength, nonce, slength, src, siv.b); |
131 | |
|
132 | 0 | memcpy (dst, siv.b, SIV_DIGEST_SIZE); |
133 | 0 | siv.b[8] &= ~0x80; |
134 | 0 | siv.b[12] &= ~0x80; |
135 | |
|
136 | 0 | ctr_crypt (ctr_cipher, nc->encrypt, AES_BLOCK_SIZE, siv.b, slength, |
137 | 0 | dst + SIV_DIGEST_SIZE, src); |
138 | 0 | } |
139 | | |
140 | | int |
141 | | siv_cmac_decrypt_message (const struct cmac128_key *cmac_key, |
142 | | const void *cmac_cipher, |
143 | | const struct nettle_cipher *nc, |
144 | | const void *ctr_cipher, |
145 | | size_t nlength, const uint8_t * nonce, |
146 | | size_t alength, const uint8_t * adata, |
147 | | size_t mlength, uint8_t * dst, const uint8_t * src) |
148 | 0 | { |
149 | 0 | union nettle_block16 siv; |
150 | 0 | union nettle_block16 ctr; |
151 | |
|
152 | 0 | memcpy (ctr.b, src, SIV_DIGEST_SIZE); |
153 | 0 | ctr.b[8] &= ~0x80; |
154 | 0 | ctr.b[12] &= ~0x80; |
155 | |
|
156 | 0 | ctr_crypt (ctr_cipher, nc->encrypt, AES_BLOCK_SIZE, ctr.b, |
157 | 0 | mlength, dst, src + SIV_DIGEST_SIZE); |
158 | | |
159 | | /* create CTR nonce */ |
160 | 0 | _siv_s2v (nc, |
161 | 0 | cmac_key, cmac_cipher, alength, adata, |
162 | 0 | nlength, nonce, mlength, dst, siv.b); |
163 | |
|
164 | 0 | return memeql_sec (siv.b, src, SIV_DIGEST_SIZE); |
165 | 0 | } |