Webserver+3d print

Dependents:   Nucleo

Committer:
Sergunb
Date:
Sat Feb 04 18:15:49 2017 +0000
Revision:
0:8918a71cdbe9
nothing else

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Sergunb 0:8918a71cdbe9 1 /**
Sergunb 0:8918a71cdbe9 2 * @file chacha20_poly1305.c
Sergunb 0:8918a71cdbe9 3 * @brief ChaCha20Poly1305 AEAD
Sergunb 0:8918a71cdbe9 4 *
Sergunb 0:8918a71cdbe9 5 * @section License
Sergunb 0:8918a71cdbe9 6 *
Sergunb 0:8918a71cdbe9 7 * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved.
Sergunb 0:8918a71cdbe9 8 *
Sergunb 0:8918a71cdbe9 9 * This file is part of CycloneCrypto Open.
Sergunb 0:8918a71cdbe9 10 *
Sergunb 0:8918a71cdbe9 11 * This program is free software; you can redistribute it and/or
Sergunb 0:8918a71cdbe9 12 * modify it under the terms of the GNU General Public License
Sergunb 0:8918a71cdbe9 13 * as published by the Free Software Foundation; either version 2
Sergunb 0:8918a71cdbe9 14 * of the License, or (at your option) any later version.
Sergunb 0:8918a71cdbe9 15 *
Sergunb 0:8918a71cdbe9 16 * This program is distributed in the hope that it will be useful,
Sergunb 0:8918a71cdbe9 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Sergunb 0:8918a71cdbe9 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Sergunb 0:8918a71cdbe9 19 * GNU General Public License for more details.
Sergunb 0:8918a71cdbe9 20 *
Sergunb 0:8918a71cdbe9 21 * You should have received a copy of the GNU General Public License
Sergunb 0:8918a71cdbe9 22 * along with this program; if not, write to the Free Software Foundation,
Sergunb 0:8918a71cdbe9 23 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Sergunb 0:8918a71cdbe9 24 *
Sergunb 0:8918a71cdbe9 25 * @author Oryx Embedded SARL (www.oryx-embedded.com)
Sergunb 0:8918a71cdbe9 26 * @version 1.7.6
Sergunb 0:8918a71cdbe9 27 **/
Sergunb 0:8918a71cdbe9 28
Sergunb 0:8918a71cdbe9 29 //Switch to the appropriate trace level
Sergunb 0:8918a71cdbe9 30 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
Sergunb 0:8918a71cdbe9 31
Sergunb 0:8918a71cdbe9 32 //Dependencies
Sergunb 0:8918a71cdbe9 33 #include <string.h>
Sergunb 0:8918a71cdbe9 34 #include "crypto.h"
Sergunb 0:8918a71cdbe9 35 #include "chacha.h"
Sergunb 0:8918a71cdbe9 36 #include "poly1305.h"
Sergunb 0:8918a71cdbe9 37 #include "chacha20_poly1305.h"
Sergunb 0:8918a71cdbe9 38 #include "debug.h"
Sergunb 0:8918a71cdbe9 39
Sergunb 0:8918a71cdbe9 40 //Check crypto library configuration
Sergunb 0:8918a71cdbe9 41 #if (CHACHA20_POLY1305_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 42
Sergunb 0:8918a71cdbe9 43
Sergunb 0:8918a71cdbe9 44 /**
Sergunb 0:8918a71cdbe9 45 * @brief Authenticated encryption using ChaCha20Poly1305
Sergunb 0:8918a71cdbe9 46 * @param[in] k key
Sergunb 0:8918a71cdbe9 47 * @param[in] kLen Length of the key
Sergunb 0:8918a71cdbe9 48 * @param[in] n Nonce
Sergunb 0:8918a71cdbe9 49 * @param[in] nLen Length of the nonce
Sergunb 0:8918a71cdbe9 50 * @param[in] a Additional authenticated data
Sergunb 0:8918a71cdbe9 51 * @param[in] aLen Length of the additional data
Sergunb 0:8918a71cdbe9 52 * @param[in] p Plaintext to be encrypted
Sergunb 0:8918a71cdbe9 53 * @param[out] c Ciphertext resulting from the encryption
Sergunb 0:8918a71cdbe9 54 * @param[in] length Total number of data bytes to be encrypted
Sergunb 0:8918a71cdbe9 55 * @param[out] t MAC resulting from the encryption process
Sergunb 0:8918a71cdbe9 56 * @param[in] tLen Length of the MAC
Sergunb 0:8918a71cdbe9 57 * @return Error code
Sergunb 0:8918a71cdbe9 58 **/
Sergunb 0:8918a71cdbe9 59
Sergunb 0:8918a71cdbe9 60 error_t chacha20Poly1305Encrypt(const uint8_t *k, size_t kLen,
Sergunb 0:8918a71cdbe9 61 const uint8_t *n, size_t nLen, const uint8_t *a, size_t aLen,
Sergunb 0:8918a71cdbe9 62 const uint8_t *p, uint8_t *c, size_t length, uint8_t *t, size_t tLen)
Sergunb 0:8918a71cdbe9 63 {
Sergunb 0:8918a71cdbe9 64 error_t error;
Sergunb 0:8918a71cdbe9 65 size_t paddingLen;
Sergunb 0:8918a71cdbe9 66 ChachaContext chachaContext;
Sergunb 0:8918a71cdbe9 67 Poly1305Context poly1305Context;
Sergunb 0:8918a71cdbe9 68 uint8_t temp[32];
Sergunb 0:8918a71cdbe9 69
Sergunb 0:8918a71cdbe9 70 //Check the length of the message-authentication code
Sergunb 0:8918a71cdbe9 71 if(tLen != 16)
Sergunb 0:8918a71cdbe9 72 return ERROR_INVALID_LENGTH;
Sergunb 0:8918a71cdbe9 73
Sergunb 0:8918a71cdbe9 74 //Initialize ChaCha20 context
Sergunb 0:8918a71cdbe9 75 error = chachaInit(&chachaContext, 20, k, kLen, n, nLen);
Sergunb 0:8918a71cdbe9 76 //Any error to report?
Sergunb 0:8918a71cdbe9 77 if(error)
Sergunb 0:8918a71cdbe9 78 return error;
Sergunb 0:8918a71cdbe9 79
Sergunb 0:8918a71cdbe9 80 //First, a Poly1305 one-time key is generated from the 256-bit key
Sergunb 0:8918a71cdbe9 81 //and nonce
Sergunb 0:8918a71cdbe9 82 chachaCipher(&chachaContext, NULL, temp, 32);
Sergunb 0:8918a71cdbe9 83
Sergunb 0:8918a71cdbe9 84 //The other 256 bits of the Chacha20 block are discarded
Sergunb 0:8918a71cdbe9 85 chachaCipher(&chachaContext, NULL, NULL, 32);
Sergunb 0:8918a71cdbe9 86
Sergunb 0:8918a71cdbe9 87 //Next, the ChaCha20 encryption function is called to encrypt the
Sergunb 0:8918a71cdbe9 88 //plaintext, using the same key and nonce
Sergunb 0:8918a71cdbe9 89 chachaCipher(&chachaContext, p, c, length);
Sergunb 0:8918a71cdbe9 90
Sergunb 0:8918a71cdbe9 91 //Initialize the Poly1305 function with the key calculated above
Sergunb 0:8918a71cdbe9 92 poly1305Init(&poly1305Context, temp);
Sergunb 0:8918a71cdbe9 93
Sergunb 0:8918a71cdbe9 94 //Compute MAC over the AAD
Sergunb 0:8918a71cdbe9 95 poly1305Update(&poly1305Context, a, aLen);
Sergunb 0:8918a71cdbe9 96
Sergunb 0:8918a71cdbe9 97 //If the length of the AAD is not an integral multiple of 16 bytes,
Sergunb 0:8918a71cdbe9 98 //then padding is required
Sergunb 0:8918a71cdbe9 99 if(aLen % 16)
Sergunb 0:8918a71cdbe9 100 {
Sergunb 0:8918a71cdbe9 101 //Compute the number of padding bytes
Sergunb 0:8918a71cdbe9 102 paddingLen = 16 - (aLen % 16);
Sergunb 0:8918a71cdbe9 103
Sergunb 0:8918a71cdbe9 104 //The padding is up to 15 zero bytes, and it brings the total
Sergunb 0:8918a71cdbe9 105 //length so far to an integral multiple of 16
Sergunb 0:8918a71cdbe9 106 memset(temp, 0, paddingLen);
Sergunb 0:8918a71cdbe9 107
Sergunb 0:8918a71cdbe9 108 //Compute MAC over the padding
Sergunb 0:8918a71cdbe9 109 poly1305Update(&poly1305Context, temp, paddingLen);
Sergunb 0:8918a71cdbe9 110 }
Sergunb 0:8918a71cdbe9 111
Sergunb 0:8918a71cdbe9 112 //Compute MAC over the ciphertext
Sergunb 0:8918a71cdbe9 113 poly1305Update(&poly1305Context, c, length);
Sergunb 0:8918a71cdbe9 114
Sergunb 0:8918a71cdbe9 115 //If the length of the ciphertext is not an integral multiple of 16 bytes,
Sergunb 0:8918a71cdbe9 116 //then padding is required
Sergunb 0:8918a71cdbe9 117 if(length % 16)
Sergunb 0:8918a71cdbe9 118 {
Sergunb 0:8918a71cdbe9 119 //Compute the number of padding bytes
Sergunb 0:8918a71cdbe9 120 paddingLen = 16 - (length % 16);
Sergunb 0:8918a71cdbe9 121
Sergunb 0:8918a71cdbe9 122 //The padding is up to 15 zero bytes, and it brings the total
Sergunb 0:8918a71cdbe9 123 //length so far to an integral multiple of 16
Sergunb 0:8918a71cdbe9 124 memset(temp, 0, paddingLen);
Sergunb 0:8918a71cdbe9 125
Sergunb 0:8918a71cdbe9 126 //Compute MAC over the padding
Sergunb 0:8918a71cdbe9 127 poly1305Update(&poly1305Context, temp, paddingLen);
Sergunb 0:8918a71cdbe9 128 }
Sergunb 0:8918a71cdbe9 129
Sergunb 0:8918a71cdbe9 130 //Encode the length of the AAD as a 64-bit little-endian integer
Sergunb 0:8918a71cdbe9 131 STORE64LE(aLen, temp);
Sergunb 0:8918a71cdbe9 132 //Compute MAC over the length field
Sergunb 0:8918a71cdbe9 133 poly1305Update(&poly1305Context, temp, sizeof(uint64_t));
Sergunb 0:8918a71cdbe9 134
Sergunb 0:8918a71cdbe9 135 //Encode the length of the ciphertext as a 64-bit little-endian integer
Sergunb 0:8918a71cdbe9 136 STORE64LE(length, temp);
Sergunb 0:8918a71cdbe9 137 //Compute MAC over the length field
Sergunb 0:8918a71cdbe9 138 poly1305Update(&poly1305Context, temp, sizeof(uint64_t));
Sergunb 0:8918a71cdbe9 139
Sergunb 0:8918a71cdbe9 140 //Compute message-authentication code
Sergunb 0:8918a71cdbe9 141 poly1305Final(&poly1305Context, t);
Sergunb 0:8918a71cdbe9 142
Sergunb 0:8918a71cdbe9 143 //Successful encryption
Sergunb 0:8918a71cdbe9 144 return NO_ERROR;
Sergunb 0:8918a71cdbe9 145 }
Sergunb 0:8918a71cdbe9 146
Sergunb 0:8918a71cdbe9 147
Sergunb 0:8918a71cdbe9 148 /**
Sergunb 0:8918a71cdbe9 149 * @brief Authenticated decryption using ChaCha20Poly1305
Sergunb 0:8918a71cdbe9 150 * @param[in] k key
Sergunb 0:8918a71cdbe9 151 * @param[in] kLen Length of the key
Sergunb 0:8918a71cdbe9 152 * @param[in] n Nonce
Sergunb 0:8918a71cdbe9 153 * @param[in] nLen Length of the nonce
Sergunb 0:8918a71cdbe9 154 * @param[in] a Additional authenticated data
Sergunb 0:8918a71cdbe9 155 * @param[in] aLen Length of the additional data
Sergunb 0:8918a71cdbe9 156 * @param[in] c Ciphertext to be decrypted
Sergunb 0:8918a71cdbe9 157 * @param[out] p Plaintext resulting from the decryption
Sergunb 0:8918a71cdbe9 158 * @param[in] length Total number of data bytes to be decrypted
Sergunb 0:8918a71cdbe9 159 * @param[in] t MAC to be verified
Sergunb 0:8918a71cdbe9 160 * @param[in] tLen Length of the MAC
Sergunb 0:8918a71cdbe9 161 * @return Error code
Sergunb 0:8918a71cdbe9 162 **/
Sergunb 0:8918a71cdbe9 163
Sergunb 0:8918a71cdbe9 164 error_t chacha20Poly1305Decrypt(const uint8_t *k, size_t kLen,
Sergunb 0:8918a71cdbe9 165 const uint8_t *n, size_t nLen, const uint8_t *a, size_t aLen,
Sergunb 0:8918a71cdbe9 166 const uint8_t *c, uint8_t *p, size_t length, const uint8_t *t, size_t tLen)
Sergunb 0:8918a71cdbe9 167 {
Sergunb 0:8918a71cdbe9 168 error_t error;
Sergunb 0:8918a71cdbe9 169 size_t paddingLen;
Sergunb 0:8918a71cdbe9 170 ChachaContext chachaContext;
Sergunb 0:8918a71cdbe9 171 Poly1305Context poly1305Context;
Sergunb 0:8918a71cdbe9 172 uint8_t temp[32];
Sergunb 0:8918a71cdbe9 173
Sergunb 0:8918a71cdbe9 174 //Check the length of the message-authentication code
Sergunb 0:8918a71cdbe9 175 if(tLen != 16)
Sergunb 0:8918a71cdbe9 176 return ERROR_INVALID_LENGTH;
Sergunb 0:8918a71cdbe9 177
Sergunb 0:8918a71cdbe9 178 //Initialize ChaCha20 context
Sergunb 0:8918a71cdbe9 179 error = chachaInit(&chachaContext, 20, k, kLen, n, nLen);
Sergunb 0:8918a71cdbe9 180 //Any error to report?
Sergunb 0:8918a71cdbe9 181 if(error)
Sergunb 0:8918a71cdbe9 182 return error;
Sergunb 0:8918a71cdbe9 183
Sergunb 0:8918a71cdbe9 184 //First, a Poly1305 one-time key is generated from the 256-bit key
Sergunb 0:8918a71cdbe9 185 //and nonce
Sergunb 0:8918a71cdbe9 186 chachaCipher(&chachaContext, NULL, temp, 32);
Sergunb 0:8918a71cdbe9 187
Sergunb 0:8918a71cdbe9 188 //The other 256 bits of the Chacha20 block are discarded
Sergunb 0:8918a71cdbe9 189 chachaCipher(&chachaContext, NULL, NULL, 32);
Sergunb 0:8918a71cdbe9 190
Sergunb 0:8918a71cdbe9 191 //Initialize the Poly1305 function with the key calculated above
Sergunb 0:8918a71cdbe9 192 poly1305Init(&poly1305Context, temp);
Sergunb 0:8918a71cdbe9 193
Sergunb 0:8918a71cdbe9 194 //Compute MAC over the AAD
Sergunb 0:8918a71cdbe9 195 poly1305Update(&poly1305Context, a, aLen);
Sergunb 0:8918a71cdbe9 196
Sergunb 0:8918a71cdbe9 197 //If the length of the AAD is not an integral multiple of 16 bytes,
Sergunb 0:8918a71cdbe9 198 //then padding is required
Sergunb 0:8918a71cdbe9 199 if(aLen % 16)
Sergunb 0:8918a71cdbe9 200 {
Sergunb 0:8918a71cdbe9 201 //Compute the number of padding bytes
Sergunb 0:8918a71cdbe9 202 paddingLen = 16 - (aLen % 16);
Sergunb 0:8918a71cdbe9 203
Sergunb 0:8918a71cdbe9 204 //The padding is up to 15 zero bytes, and it brings the total
Sergunb 0:8918a71cdbe9 205 //length so far to an integral multiple of 16
Sergunb 0:8918a71cdbe9 206 memset(temp, 0, paddingLen);
Sergunb 0:8918a71cdbe9 207
Sergunb 0:8918a71cdbe9 208 //Compute MAC over the padding
Sergunb 0:8918a71cdbe9 209 poly1305Update(&poly1305Context, temp, paddingLen);
Sergunb 0:8918a71cdbe9 210 }
Sergunb 0:8918a71cdbe9 211
Sergunb 0:8918a71cdbe9 212 //Compute MAC over the ciphertext
Sergunb 0:8918a71cdbe9 213 poly1305Update(&poly1305Context, c, length);
Sergunb 0:8918a71cdbe9 214
Sergunb 0:8918a71cdbe9 215 //If the length of the ciphertext is not an integral multiple of 16 bytes,
Sergunb 0:8918a71cdbe9 216 //then padding is required
Sergunb 0:8918a71cdbe9 217 if(length % 16)
Sergunb 0:8918a71cdbe9 218 {
Sergunb 0:8918a71cdbe9 219 //Compute the number of padding bytes
Sergunb 0:8918a71cdbe9 220 paddingLen = 16 - (length % 16);
Sergunb 0:8918a71cdbe9 221
Sergunb 0:8918a71cdbe9 222 //The padding is up to 15 zero bytes, and it brings the total
Sergunb 0:8918a71cdbe9 223 //length so far to an integral multiple of 16
Sergunb 0:8918a71cdbe9 224 memset(temp, 0, paddingLen);
Sergunb 0:8918a71cdbe9 225
Sergunb 0:8918a71cdbe9 226 //Compute MAC over the padding
Sergunb 0:8918a71cdbe9 227 poly1305Update(&poly1305Context, temp, paddingLen);
Sergunb 0:8918a71cdbe9 228 }
Sergunb 0:8918a71cdbe9 229
Sergunb 0:8918a71cdbe9 230 //Encode the length of the AAD as a 64-bit little-endian integer
Sergunb 0:8918a71cdbe9 231 STORE64LE(aLen, temp);
Sergunb 0:8918a71cdbe9 232 //Compute MAC over the length field
Sergunb 0:8918a71cdbe9 233 poly1305Update(&poly1305Context, temp, sizeof(uint64_t));
Sergunb 0:8918a71cdbe9 234
Sergunb 0:8918a71cdbe9 235 //Encode the length of the ciphertext as a 64-bit little-endian integer
Sergunb 0:8918a71cdbe9 236 STORE64LE(length, temp);
Sergunb 0:8918a71cdbe9 237 //Compute MAC over the length field
Sergunb 0:8918a71cdbe9 238 poly1305Update(&poly1305Context, temp, sizeof(uint64_t));
Sergunb 0:8918a71cdbe9 239
Sergunb 0:8918a71cdbe9 240 //Compute message-authentication code
Sergunb 0:8918a71cdbe9 241 poly1305Final(&poly1305Context, temp);
Sergunb 0:8918a71cdbe9 242
Sergunb 0:8918a71cdbe9 243 //Finally, we decrypt the ciphertext
Sergunb 0:8918a71cdbe9 244 chachaCipher(&chachaContext, c, p, length);
Sergunb 0:8918a71cdbe9 245
Sergunb 0:8918a71cdbe9 246 //The calculated tag is bitwise compared to the received tag. The
Sergunb 0:8918a71cdbe9 247 //message is authenticated if and only if the tags match
Sergunb 0:8918a71cdbe9 248 if(memcmp(temp, t, tLen))
Sergunb 0:8918a71cdbe9 249 return ERROR_FAILURE;
Sergunb 0:8918a71cdbe9 250
Sergunb 0:8918a71cdbe9 251 //Successful encryption
Sergunb 0:8918a71cdbe9 252 return NO_ERROR;
Sergunb 0:8918a71cdbe9 253 }
Sergunb 0:8918a71cdbe9 254
Sergunb 0:8918a71cdbe9 255 #endif
Sergunb 0:8918a71cdbe9 256