Mention dependencies on GNU make and GNU GMP in the README file.
[gd/nettle] / siv-cmac.c
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 {
60   union nettle_block16 D, S, T;
61   static const union nettle_block16 const_zero = {.b = 0 };
62   struct cmac128_ctx cmac_ctx;
63   assert (nlength >= SIV_MIN_NONCE_SIZE);
64
65   cmac128_init(&cmac_ctx);
66   cmac128_update (&cmac_ctx, cmac_cipher, nc->encrypt, 16, const_zero.b);
67   cmac128_digest (&cmac_ctx, cmac_key, cmac_cipher, nc->encrypt, 16, D.b);
68
69   block16_mulx_be (&D, &D);
70   cmac128_update (&cmac_ctx, cmac_cipher, nc->encrypt, alength, adata);
71   cmac128_digest (&cmac_ctx, cmac_key, cmac_cipher, nc->encrypt, 16, S.b);
72   block16_xor (&D, &S);
73
74   block16_mulx_be (&D, &D);
75   cmac128_update (&cmac_ctx, cmac_cipher, nc->encrypt, nlength, nonce);
76   cmac128_digest (&cmac_ctx, cmac_key, cmac_cipher, nc->encrypt, 16, S.b);
77   block16_xor (&D, &S);
78
79   /* Sn */
80   if (plength >= 16)
81     {
82       cmac128_update (&cmac_ctx, cmac_cipher, nc->encrypt, plength - 16, pdata);
83
84       pdata += plength - 16;
85
86       block16_xor_bytes (&T, &D, pdata);
87     }
88   else
89     {
90       union nettle_block16 pad;
91
92       block16_mulx_be (&T, &D);
93       memcpy (pad.b, pdata, plength);
94       pad.b[plength] = 0x80;
95       if (plength + 1 < 16)
96         memset (&pad.b[plength + 1], 0, 16 - plength - 1);
97
98       block16_xor (&T, &pad);
99     }
100
101   cmac128_update (&cmac_ctx, cmac_cipher, nc->encrypt, 16, T.b);
102   cmac128_digest (&cmac_ctx, cmac_key, cmac_cipher, nc->encrypt, 16, v);
103 }
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 {
109   nc->set_encrypt_key (cmac_cipher, key);
110   cmac128_set_key (cmac_key, cmac_cipher, nc->encrypt);
111   nc->set_encrypt_key (siv_cipher, key + nc->key_size);
112 }
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 {
123   union nettle_block16 siv;
124   size_t slength;
125
126   assert (clength >= SIV_DIGEST_SIZE);
127   slength = clength - SIV_DIGEST_SIZE;
128
129   /* create CTR nonce */
130   _siv_s2v (nc, cmac_key, cmac_cipher, alength, adata, nlength, nonce, slength, src, siv.b);
131
132   memcpy (dst, siv.b, SIV_DIGEST_SIZE);
133   siv.b[8] &= ~0x80;
134   siv.b[12] &= ~0x80;
135
136   ctr_crypt (ctr_cipher, nc->encrypt, AES_BLOCK_SIZE, siv.b, slength,
137              dst + SIV_DIGEST_SIZE, src);
138 }
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 {
149   union nettle_block16 siv;
150   union nettle_block16 ctr;
151
152   memcpy (ctr.b, src, SIV_DIGEST_SIZE);
153   ctr.b[8] &= ~0x80;
154   ctr.b[12] &= ~0x80;
155
156   ctr_crypt (ctr_cipher, nc->encrypt, AES_BLOCK_SIZE, ctr.b,
157              mlength, dst, src + SIV_DIGEST_SIZE);
158
159   /* create CTR nonce */
160   _siv_s2v (nc,
161             cmac_key, cmac_cipher, alength, adata,
162             nlength, nonce, mlength, dst, siv.b);
163
164   return memeql_sec (siv.b, src, SIV_DIGEST_SIZE);
165 }