Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
poly1305.c
00001 /** 00002 * @file poly1305.c 00003 * @brief Poly1305 message-authentication code 00004 * 00005 * @section License 00006 * 00007 * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved. 00008 * 00009 * This file is part of CycloneCrypto Open. 00010 * 00011 * This program is free software; you can redistribute it and/or 00012 * modify it under the terms of the GNU General Public License 00013 * as published by the Free Software Foundation; either version 2 00014 * of the License, or (at your option) any later version. 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU General Public License 00022 * along with this program; if not, write to the Free Software Foundation, 00023 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00024 * 00025 * @author Oryx Embedded SARL (www.oryx-embedded.com) 00026 * @version 1.7.6 00027 **/ 00028 00029 //Switch to the appropriate trace level 00030 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL 00031 00032 //Dependencies 00033 #include <string.h> 00034 #include "crypto.h" 00035 #include "poly1305.h" 00036 #include "debug.h" 00037 00038 //Check crypto library configuration 00039 #if (POLY1305_SUPPORT == ENABLED) 00040 00041 00042 /** 00043 * @brief Initialize Poly1305 message-authentication code computation 00044 * @param[in] context Pointer to the Poly1305 context to initialize 00045 * @param[in] key Pointer to the 256-bit key 00046 **/ 00047 00048 void poly1305Init(Poly1305Context *context, const uint8_t *key) 00049 { 00050 //The 256-bit key is partitioned into two parts, called r and s 00051 context->r[0] = LOAD32LE(key); 00052 context->r[1] = LOAD32LE(key + 4); 00053 context->r[2] = LOAD32LE(key + 8); 00054 context->r[3] = LOAD32LE(key + 12); 00055 context->s[0] = LOAD32LE(key + 16); 00056 context->s[1] = LOAD32LE(key + 20); 00057 context->s[2] = LOAD32LE(key + 24); 00058 context->s[3] = LOAD32LE(key + 28); 00059 00060 //Certain bits of r are required to be 0 00061 context->r[0] &= 0x0FFFFFFF; 00062 context->r[1] &= 0x0FFFFFFC; 00063 context->r[2] &= 0x0FFFFFFC; 00064 context->r[3] &= 0x0FFFFFFC; 00065 00066 //The accumulator is set to zero 00067 context->a[0] = 0; 00068 context->a[1] = 0; 00069 context->a[2] = 0; 00070 context->a[3] = 0; 00071 context->a[4] = 0; 00072 context->a[5] = 0; 00073 context->a[6] = 0; 00074 context->a[7] = 0; 00075 00076 //Number of bytes in the buffer 00077 context->size = 0; 00078 } 00079 00080 00081 /** 00082 * @brief Update Poly1305 message-authentication code computation 00083 * @param[in] context Pointer to the Poly1305 context 00084 * @param[in] data Pointer to the input message 00085 * @param[in] length Length of the input message 00086 **/ 00087 00088 void poly1305Update(Poly1305Context *context, const void *data, size_t length) 00089 { 00090 size_t n; 00091 00092 //Process the incoming data 00093 while(length > 0) 00094 { 00095 //The buffer can hold at most 16 bytes 00096 n = MIN(length, 16 - context->size); 00097 00098 //Copy the data to the buffer 00099 memcpy(context->buffer + context->size, data, n); 00100 00101 //Update the Poly1305 context 00102 context->size += n; 00103 //Advance the data pointer 00104 data = (uint8_t *) data + n; 00105 //Remaining bytes to process 00106 length -= n; 00107 00108 //Process message in 16-byte blocks 00109 if(context->size == 16) 00110 { 00111 //Transform the 16-byte block 00112 poly1305ProcessBlock(context); 00113 //Empty the buffer 00114 context->size = 0; 00115 } 00116 } 00117 } 00118 00119 00120 /** 00121 * @brief Finalize Poly1305 message-authentication code computation 00122 * @param[in] context Pointer to the Poly1305 context 00123 * @param[out] tag Calculated message-authentication code 00124 **/ 00125 00126 void poly1305Final(Poly1305Context *context, uint8_t *tag) 00127 { 00128 uint32_t mask; 00129 uint32_t b[4]; 00130 00131 //Process the last block 00132 if(context->size != 0) 00133 poly1305ProcessBlock(context); 00134 00135 //Save the accumulator 00136 b[0] = context->a[0] & 0xFFFFFFFF; 00137 b[1] = context->a[1] & 0xFFFFFFFF; 00138 b[2] = context->a[2] & 0xFFFFFFFF; 00139 b[3] = context->a[3] & 0xFFFFFFFF; 00140 00141 //Compute a + 5 00142 context->a[0] += 5; 00143 00144 //Propagate the carry 00145 context->a[1] += context->a[0] >> 32; 00146 context->a[2] += context->a[1] >> 32; 00147 context->a[3] += context->a[2] >> 32; 00148 context->a[4] += context->a[3] >> 32; 00149 00150 //If (a + 5) >= 2^130, form a mask with the value 0x00000000. Else, form 00151 //a mask with the value 0xffffffff 00152 mask = ((context->a[4] & 0x04) >> 2) - 1; 00153 00154 //Select between ((a - (2^130 - 5)) % 2^128) and (a % 2^128) 00155 context->a[0] = (context->a[0] & ~mask) | (b[0] & mask); 00156 context->a[1] = (context->a[1] & ~mask) | (b[1] & mask); 00157 context->a[2] = (context->a[2] & ~mask) | (b[2] & mask); 00158 context->a[3] = (context->a[3] & ~mask) | (b[3] & mask); 00159 00160 //Finally, the value of the secret key s is added to the accumulator 00161 context->a[0] += context->s[0]; 00162 context->a[1] += context->s[1]; 00163 context->a[2] += context->s[2]; 00164 context->a[3] += context->s[3]; 00165 00166 //Propagate the carry 00167 context->a[1] += context->a[0] >> 32; 00168 context->a[2] += context->a[1] >> 32; 00169 context->a[3] += context->a[2] >> 32; 00170 context->a[4] += context->a[3] >> 32; 00171 00172 //We only consider the least significant bits 00173 b[0] = context->a[0] & 0xFFFFFFFF; 00174 b[1] = context->a[1] & 0xFFFFFFFF; 00175 b[2] = context->a[2] & 0xFFFFFFFF; 00176 b[3] = context->a[3] & 0xFFFFFFFF; 00177 00178 //The result is serialized as a little-endian number, producing 00179 //the 16 byte tag 00180 STORE32LE(b[0], tag); 00181 STORE32LE(b[1], tag + 4); 00182 STORE32LE(b[2], tag + 8); 00183 STORE32LE(b[3], tag + 12); 00184 00185 //Clear the accumulator 00186 context->a[0] = 0; 00187 context->a[1] = 0; 00188 context->a[2] = 0; 00189 context->a[3] = 0; 00190 context->a[4] = 0; 00191 context->a[5] = 0; 00192 context->a[6] = 0; 00193 context->a[7] = 0; 00194 00195 //Clear r and s 00196 context->r[0] = 0; 00197 context->r[1] = 0; 00198 context->r[2] = 0; 00199 context->r[3] = 0; 00200 context->s[0] = 0; 00201 context->s[1] = 0; 00202 context->s[2] = 0; 00203 context->s[3] = 0; 00204 } 00205 00206 00207 /** 00208 * @brief Process message in 16-byte blocks 00209 * @param[in] context Pointer to the Poly1305 context 00210 **/ 00211 00212 void poly1305ProcessBlock(Poly1305Context *context) 00213 { 00214 uint32_t a[8]; 00215 uint32_t r[4]; 00216 uint_t n; 00217 00218 //Retrieve the length of the last block 00219 n = context->size; 00220 00221 //Add one bit beyond the number of octets. For a 16-byte block, 00222 //this is equivalent to adding 2^128 to the number. For the shorter 00223 //block, it can be 2^120, 2^112, or any power of two that is evenly 00224 //divisible by 8, all the way down to 2^8 00225 context->buffer[n++] = 0x01; 00226 00227 //If the resulting block is not 17 bytes long (the last block), 00228 //pad it with zeros 00229 while(n < 17) 00230 context->buffer[n++] = 0x00; 00231 00232 //Read the block as a little-endian number 00233 a[0] = LOAD32LE(context->buffer); 00234 a[1] = LOAD32LE(context->buffer + 4); 00235 a[2] = LOAD32LE(context->buffer + 8); 00236 a[3] = LOAD32LE(context->buffer + 12); 00237 a[4] = context->buffer[16]; 00238 00239 //Add this number to the accumulator 00240 context->a[0] += a[0]; 00241 context->a[1] += a[1]; 00242 context->a[2] += a[2]; 00243 context->a[3] += a[3]; 00244 context->a[4] += a[4]; 00245 00246 //Propagate the carry 00247 context->a[1] += context->a[0] >> 32; 00248 context->a[2] += context->a[1] >> 32; 00249 context->a[3] += context->a[2] >> 32; 00250 context->a[4] += context->a[3] >> 32; 00251 00252 //We only consider the least significant bits 00253 a[0] = context->a[0] & 0xFFFFFFFF; 00254 a[1] = context->a[1] & 0xFFFFFFFF; 00255 a[2] = context->a[2] & 0xFFFFFFFF; 00256 a[3] = context->a[3] & 0xFFFFFFFF; 00257 a[4] = context->a[4] & 0xFFFFFFFF; 00258 00259 //Copy r 00260 r[0] = context->r[0]; 00261 r[1] = context->r[1]; 00262 r[2] = context->r[2]; 00263 r[3] = context->r[3]; 00264 00265 //Multiply the accumulator by r 00266 context->a[0] = (uint64_t) a[0] * r[0]; 00267 context->a[1] = (uint64_t) a[0] * r[1] + (uint64_t) a[1] * r[0]; 00268 context->a[2] = (uint64_t) a[0] * r[2] + (uint64_t) a[1] * r[1] + (uint64_t) a[2] * r[0]; 00269 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]; 00270 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]; 00271 context->a[5] = (uint64_t) a[2] * r[3] + (uint64_t) a[3] * r[2] + (uint64_t) a[4] * r[1]; 00272 context->a[6] = (uint64_t) a[3] * r[3] + (uint64_t) a[4] * r[2]; 00273 context->a[7] = (uint64_t) a[4] * r[3]; 00274 00275 //Propagate the carry 00276 context->a[1] += context->a[0] >> 32; 00277 context->a[2] += context->a[1] >> 32; 00278 context->a[3] += context->a[2] >> 32; 00279 context->a[4] += context->a[3] >> 32; 00280 context->a[5] += context->a[4] >> 32; 00281 context->a[6] += context->a[5] >> 32; 00282 context->a[7] += context->a[6] >> 32; 00283 00284 //Save the high part of the accumulator 00285 a[0] = context->a[4] & 0xFFFFFFFC; 00286 a[1] = context->a[5] & 0xFFFFFFFF; 00287 a[2] = context->a[6] & 0xFFFFFFFF; 00288 a[3] = context->a[7] & 0xFFFFFFFF; 00289 00290 //We only consider the least significant bits 00291 context->a[0] &= 0xFFFFFFFF; 00292 context->a[1] &= 0xFFFFFFFF; 00293 context->a[2] &= 0xFFFFFFFF; 00294 context->a[3] &= 0xFFFFFFFF; 00295 context->a[4] &= 0x00000003; 00296 00297 //Perform fast modular reduction (first pass) 00298 context->a[0] += a[0]; 00299 context->a[0] += (a[0] >> 2) | (a[1] << 30); 00300 context->a[1] += a[1]; 00301 context->a[1] += (a[1] >> 2) | (a[2] << 30); 00302 context->a[2] += a[2]; 00303 context->a[2] += (a[2] >> 2) | (a[3] << 30); 00304 context->a[3] += a[3]; 00305 context->a[3] += (a[3] >> 2); 00306 00307 //Propagate the carry 00308 context->a[1] += context->a[0] >> 32; 00309 context->a[2] += context->a[1] >> 32; 00310 context->a[3] += context->a[2] >> 32; 00311 context->a[4] += context->a[3] >> 32; 00312 00313 //Save the high part of the accumulator 00314 a[0] = context->a[4] & 0xFFFFFFFC; 00315 00316 //We only consider the least significant bits 00317 context->a[0] &= 0xFFFFFFFF; 00318 context->a[1] &= 0xFFFFFFFF; 00319 context->a[2] &= 0xFFFFFFFF; 00320 context->a[3] &= 0xFFFFFFFF; 00321 context->a[4] &= 0x00000003; 00322 00323 //Perform fast modular reduction (second pass) 00324 context->a[0] += a[0]; 00325 context->a[0] += a[0] >> 2; 00326 00327 //Propagate the carry 00328 context->a[1] += context->a[0] >> 32; 00329 context->a[2] += context->a[1] >> 32; 00330 context->a[3] += context->a[2] >> 32; 00331 context->a[4] += context->a[3] >> 32; 00332 00333 //We only consider the least significant bits 00334 context->a[0] &= 0xFFFFFFFF; 00335 context->a[1] &= 0xFFFFFFFF; 00336 context->a[2] &= 0xFFFFFFFF; 00337 context->a[3] &= 0xFFFFFFFF; 00338 context->a[4] &= 0x00000003; 00339 } 00340 00341 #endif 00342
Generated on Tue Jul 12 2022 17:10:15 by
1.7.2