Sergey Pastor / 1

Dependents:   Nucleo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers poly1305.c Source File

poly1305.c

Go to the documentation of this file.
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