poly1305.c
Go to the documentation of this file.
1 /**
2  * @file poly1305.c
3  * @brief Poly1305 message-authentication code
4  *
5  * @section License
6  *
7  * Copyright (C) 2010-2018 Oryx Embedded SARL. All rights reserved.
8  *
9  * This file is part of CycloneCrypto Open.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24  *
25  * @author Oryx Embedded SARL (www.oryx-embedded.com)
26  * @version 1.9.0
27  **/
28 
29 //Switch to the appropriate trace level
30 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
31 
32 //Dependencies
33 #include "core/crypto.h"
34 #include "mac/poly1305.h"
35 #include "debug.h"
36 
37 //Check crypto library configuration
38 #if (POLY1305_SUPPORT == ENABLED)
39 
40 
41 /**
42  * @brief Initialize Poly1305 message-authentication code computation
43  * @param[in] context Pointer to the Poly1305 context to initialize
44  * @param[in] key Pointer to the 256-bit key
45  **/
46 
47 void poly1305Init(Poly1305Context *context, const uint8_t *key)
48 {
49  //The 256-bit key is partitioned into two parts, called r and s
50  context->r[0] = LOAD32LE(key);
51  context->r[1] = LOAD32LE(key + 4);
52  context->r[2] = LOAD32LE(key + 8);
53  context->r[3] = LOAD32LE(key + 12);
54  context->s[0] = LOAD32LE(key + 16);
55  context->s[1] = LOAD32LE(key + 20);
56  context->s[2] = LOAD32LE(key + 24);
57  context->s[3] = LOAD32LE(key + 28);
58 
59  //Certain bits of r are required to be 0
60  context->r[0] &= 0x0FFFFFFF;
61  context->r[1] &= 0x0FFFFFFC;
62  context->r[2] &= 0x0FFFFFFC;
63  context->r[3] &= 0x0FFFFFFC;
64 
65  //The accumulator is set to zero
66  context->a[0] = 0;
67  context->a[1] = 0;
68  context->a[2] = 0;
69  context->a[3] = 0;
70  context->a[4] = 0;
71  context->a[5] = 0;
72  context->a[6] = 0;
73  context->a[7] = 0;
74 
75  //Number of bytes in the buffer
76  context->size = 0;
77 }
78 
79 
80 /**
81  * @brief Update Poly1305 message-authentication code computation
82  * @param[in] context Pointer to the Poly1305 context
83  * @param[in] data Pointer to the input message
84  * @param[in] length Length of the input message
85  **/
86 
87 void poly1305Update(Poly1305Context *context, const void *data, size_t length)
88 {
89  size_t n;
90 
91  //Process the incoming data
92  while(length > 0)
93  {
94  //The buffer can hold at most 16 bytes
95  n = MIN(length, 16 - context->size);
96 
97  //Copy the data to the buffer
98  cryptoMemcpy(context->buffer + context->size, data, n);
99 
100  //Update the Poly1305 context
101  context->size += n;
102  //Advance the data pointer
103  data = (uint8_t *) data + n;
104  //Remaining bytes to process
105  length -= n;
106 
107  //Process message in 16-byte blocks
108  if(context->size == 16)
109  {
110  //Transform the 16-byte block
111  poly1305ProcessBlock(context);
112  //Empty the buffer
113  context->size = 0;
114  }
115  }
116 }
117 
118 
119 /**
120  * @brief Finalize Poly1305 message-authentication code computation
121  * @param[in] context Pointer to the Poly1305 context
122  * @param[out] tag Calculated message-authentication code
123  **/
124 
125 void poly1305Final(Poly1305Context *context, uint8_t *tag)
126 {
127  uint32_t mask;
128  uint32_t b[4];
129 
130  //Process the last block
131  if(context->size != 0)
132  poly1305ProcessBlock(context);
133 
134  //Save the accumulator
135  b[0] = context->a[0] & 0xFFFFFFFF;
136  b[1] = context->a[1] & 0xFFFFFFFF;
137  b[2] = context->a[2] & 0xFFFFFFFF;
138  b[3] = context->a[3] & 0xFFFFFFFF;
139 
140  //Compute a + 5
141  context->a[0] += 5;
142 
143  //Propagate the carry
144  context->a[1] += context->a[0] >> 32;
145  context->a[2] += context->a[1] >> 32;
146  context->a[3] += context->a[2] >> 32;
147  context->a[4] += context->a[3] >> 32;
148 
149  //If (a + 5) >= 2^130, form a mask with the value 0x00000000. Else,
150  //form a mask with the value 0xffffffff
151  mask = ((context->a[4] & 0x04) >> 2) - 1;
152 
153  //Select between ((a - (2^130 - 5)) % 2^128) and (a % 2^128)
154  context->a[0] = (context->a[0] & ~mask) | (b[0] & mask);
155  context->a[1] = (context->a[1] & ~mask) | (b[1] & mask);
156  context->a[2] = (context->a[2] & ~mask) | (b[2] & mask);
157  context->a[3] = (context->a[3] & ~mask) | (b[3] & mask);
158 
159  //Finally, the value of the secret key s is added to the accumulator
160  context->a[0] += context->s[0];
161  context->a[1] += context->s[1];
162  context->a[2] += context->s[2];
163  context->a[3] += context->s[3];
164 
165  //Propagate the carry
166  context->a[1] += context->a[0] >> 32;
167  context->a[2] += context->a[1] >> 32;
168  context->a[3] += context->a[2] >> 32;
169  context->a[4] += context->a[3] >> 32;
170 
171  //We only consider the least significant bits
172  b[0] = context->a[0] & 0xFFFFFFFF;
173  b[1] = context->a[1] & 0xFFFFFFFF;
174  b[2] = context->a[2] & 0xFFFFFFFF;
175  b[3] = context->a[3] & 0xFFFFFFFF;
176 
177  //The result is serialized as a little-endian number, producing
178  //the 16 byte tag
179  STORE32LE(b[0], tag);
180  STORE32LE(b[1], tag + 4);
181  STORE32LE(b[2], tag + 8);
182  STORE32LE(b[3], tag + 12);
183 
184  //Clear the accumulator
185  context->a[0] = 0;
186  context->a[1] = 0;
187  context->a[2] = 0;
188  context->a[3] = 0;
189  context->a[4] = 0;
190  context->a[5] = 0;
191  context->a[6] = 0;
192  context->a[7] = 0;
193 
194  //Clear r and s
195  context->r[0] = 0;
196  context->r[1] = 0;
197  context->r[2] = 0;
198  context->r[3] = 0;
199  context->s[0] = 0;
200  context->s[1] = 0;
201  context->s[2] = 0;
202  context->s[3] = 0;
203 }
204 
205 
206 /**
207  * @brief Process message in 16-byte blocks
208  * @param[in] context Pointer to the Poly1305 context
209  **/
210 
212 {
213  uint32_t a[5];
214  uint32_t r[4];
215  uint_t n;
216 
217  //Retrieve the length of the last block
218  n = context->size;
219 
220  //Add one bit beyond the number of octets. For a 16-byte block,
221  //this is equivalent to adding 2^128 to the number. For the shorter
222  //block, it can be 2^120, 2^112, or any power of two that is evenly
223  //divisible by 8, all the way down to 2^8
224  context->buffer[n++] = 0x01;
225 
226  //If the resulting block is not 17 bytes long (the last block),
227  //pad it with zeros
228  while(n < 17)
229  context->buffer[n++] = 0x00;
230 
231  //Read the block as a little-endian number
232  a[0] = LOAD32LE(context->buffer);
233  a[1] = LOAD32LE(context->buffer + 4);
234  a[2] = LOAD32LE(context->buffer + 8);
235  a[3] = LOAD32LE(context->buffer + 12);
236  a[4] = context->buffer[16];
237 
238  //Add this number to the accumulator
239  context->a[0] += a[0];
240  context->a[1] += a[1];
241  context->a[2] += a[2];
242  context->a[3] += a[3];
243  context->a[4] += a[4];
244 
245  //Propagate the carry
246  context->a[1] += context->a[0] >> 32;
247  context->a[2] += context->a[1] >> 32;
248  context->a[3] += context->a[2] >> 32;
249  context->a[4] += context->a[3] >> 32;
250 
251  //We only consider the least significant bits
252  a[0] = context->a[0] & 0xFFFFFFFF;
253  a[1] = context->a[1] & 0xFFFFFFFF;
254  a[2] = context->a[2] & 0xFFFFFFFF;
255  a[3] = context->a[3] & 0xFFFFFFFF;
256  a[4] = context->a[4] & 0xFFFFFFFF;
257 
258  //Copy r
259  r[0] = context->r[0];
260  r[1] = context->r[1];
261  r[2] = context->r[2];
262  r[3] = context->r[3];
263 
264  //Multiply the accumulator by r
265  context->a[0] = (uint64_t) a[0] * r[0];
266  context->a[1] = (uint64_t) a[0] * r[1] + (uint64_t) a[1] * r[0];
267  context->a[2] = (uint64_t) a[0] * r[2] + (uint64_t) a[1] * r[1] + (uint64_t) a[2] * r[0];
268  context->a[3] = (uint64_t) a[0] * r[3] + (uint64_t) a[1] * r[2] + (uint64_t) a[2] * r[1] + (uint64_t) a[3] * r[0];
269  context->a[4] = (uint64_t) a[1] * r[3] + (uint64_t) a[2] * r[2] + (uint64_t) a[3] * r[1] + (uint64_t) a[4] * r[0];
270  context->a[5] = (uint64_t) a[2] * r[3] + (uint64_t) a[3] * r[2] + (uint64_t) a[4] * r[1];
271  context->a[6] = (uint64_t) a[3] * r[3] + (uint64_t) a[4] * r[2];
272  context->a[7] = (uint64_t) a[4] * r[3];
273 
274  //Propagate the carry
275  context->a[1] += context->a[0] >> 32;
276  context->a[2] += context->a[1] >> 32;
277  context->a[3] += context->a[2] >> 32;
278  context->a[4] += context->a[3] >> 32;
279  context->a[5] += context->a[4] >> 32;
280  context->a[6] += context->a[5] >> 32;
281  context->a[7] += context->a[6] >> 32;
282 
283  //Save the high part of the accumulator
284  a[0] = context->a[4] & 0xFFFFFFFC;
285  a[1] = context->a[5] & 0xFFFFFFFF;
286  a[2] = context->a[6] & 0xFFFFFFFF;
287  a[3] = context->a[7] & 0xFFFFFFFF;
288 
289  //We only consider the least significant bits
290  context->a[0] &= 0xFFFFFFFF;
291  context->a[1] &= 0xFFFFFFFF;
292  context->a[2] &= 0xFFFFFFFF;
293  context->a[3] &= 0xFFFFFFFF;
294  context->a[4] &= 0x00000003;
295 
296  //Perform fast modular reduction (first pass)
297  context->a[0] += a[0];
298  context->a[0] += (a[0] >> 2) | (a[1] << 30);
299  context->a[1] += a[1];
300  context->a[1] += (a[1] >> 2) | (a[2] << 30);
301  context->a[2] += a[2];
302  context->a[2] += (a[2] >> 2) | (a[3] << 30);
303  context->a[3] += a[3];
304  context->a[3] += (a[3] >> 2);
305 
306  //Propagate the carry
307  context->a[1] += context->a[0] >> 32;
308  context->a[2] += context->a[1] >> 32;
309  context->a[3] += context->a[2] >> 32;
310  context->a[4] += context->a[3] >> 32;
311 
312  //Save the high part of the accumulator
313  a[0] = context->a[4] & 0xFFFFFFFC;
314 
315  //We only consider the least significant bits
316  context->a[0] &= 0xFFFFFFFF;
317  context->a[1] &= 0xFFFFFFFF;
318  context->a[2] &= 0xFFFFFFFF;
319  context->a[3] &= 0xFFFFFFFF;
320  context->a[4] &= 0x00000003;
321 
322  //Perform fast modular reduction (second pass)
323  context->a[0] += a[0];
324  context->a[0] += a[0] >> 2;
325 
326  //Propagate the carry
327  context->a[1] += context->a[0] >> 32;
328  context->a[2] += context->a[1] >> 32;
329  context->a[3] += context->a[2] >> 32;
330  context->a[4] += context->a[3] >> 32;
331 
332  //We only consider the least significant bits
333  context->a[0] &= 0xFFFFFFFF;
334  context->a[1] &= 0xFFFFFFFF;
335  context->a[2] &= 0xFFFFFFFF;
336  context->a[3] &= 0xFFFFFFFF;
337  context->a[4] &= 0x00000003;
338 }
339 
340 #endif
uint32_t s[4]
Definition: poly1305.h:48
#define cryptoMemcpy(dest, src, length)
Definition: crypto.h:590
Debugging facilities.
void poly1305Update(Poly1305Context *context, const void *data, size_t length)
Update Poly1305 message-authentication code computation.
Definition: poly1305.c:87
General definitions for cryptographic algorithms.
void poly1305Init(Poly1305Context *context, const uint8_t *key)
Initialize Poly1305 message-authentication code computation.
Definition: poly1305.c:47
Poly1305 context.
Definition: poly1305.h:45
uint8_t a
Definition: ndp.h:407
void poly1305ProcessBlock(Poly1305Context *context)
Process message in 16-byte blocks.
Definition: poly1305.c:211
uint8_t mask
Definition: web_socket.h:315
uint32_t r[4]
Definition: poly1305.h:47
size_t size
Definition: poly1305.h:51
#define STORE32LE(a, p)
Definition: cpu_endian.h:261
#define MIN(a, b)
Definition: os_port.h:60
unsigned int uint_t
Definition: compiler_port.h:43
uint8_t data[]
Definition: dtls_misc.h:167
uint32_t r
Definition: ndp.h:342
uint64_t a[8]
Definition: poly1305.h:49
Poly1305 message-authentication code.
#define LOAD32LE(p)
Definition: cpu_endian.h:185
uint8_t length
Definition: dtls_misc.h:140
uint8_t n
uint8_t b[6]
Definition: dtls_misc.h:130
void poly1305Final(Poly1305Context *context, uint8_t *tag)
Finalize Poly1305 message-authentication code computation.
Definition: poly1305.c:125
uint8_t buffer[17]
Definition: poly1305.h:50