Line data Source code
1 : /* chacha-crypt.c 2 : 3 : The crypt function in the ChaCha stream cipher. 4 : Heavily based on the Salsa20 implementation in Nettle. 5 : 6 : Copyright (C) 2014 Niels Möller 7 : Copyright (C) 2013 Joachim Strömbergson 8 : Copyright (C) 2012 Simon Josefsson 9 : 10 : This file is part of GNU Nettle. 11 : 12 : GNU Nettle is free software: you can redistribute it and/or 13 : modify it under the terms of either: 14 : 15 : * the GNU Lesser General Public License as published by the Free 16 : Software Foundation; either version 3 of the License, or (at your 17 : option) any later version. 18 : 19 : or 20 : 21 : * the GNU General Public License as published by the Free 22 : Software Foundation; either version 2 of the License, or (at your 23 : option) any later version. 24 : 25 : or both in parallel, as here. 26 : 27 : GNU Nettle is distributed in the hope that it will be useful, 28 : but WITHOUT ANY WARRANTY; without even the implied warranty of 29 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 30 : General Public License for more details. 31 : 32 : You should have received copies of the GNU General Public License and 33 : the GNU Lesser General Public License along with this program. If 34 : not, see http://www.gnu.org/licenses/. 35 : */ 36 : 37 : /* Based on: 38 : chacha-ref.c version 2008.01.20. 39 : D. J. Bernstein 40 : Public domain. 41 : */ 42 : 43 : #if HAVE_CONFIG_H 44 : # include "config.h" 45 : #endif 46 : 47 : #include <string.h> 48 : 49 : #include "chacha.h" 50 : #include "chacha-internal.h" 51 : 52 : #include <nettle/macros.h> 53 : #include <nettle/memxor.h> 54 : 55 : #define CHACHA_ROUNDS 20 56 : 57 : void 58 20 : chacha_crypt(struct chacha_ctx *ctx, 59 : size_t length, 60 : uint8_t *c, 61 : const uint8_t *m) 62 : { 63 20 : if (!length) 64 : return; 65 : 66 60 : for (;;) 67 20 : { 68 40 : uint32_t x[_CHACHA_STATE_LENGTH]; 69 : 70 40 : _chacha_core (x, ctx->state, CHACHA_ROUNDS); 71 : 72 40 : ctx->state[13] += (++ctx->state[12] == 0); 73 : 74 : /* stopping at 2^70 length per nonce is user's responsibility */ 75 : 76 40 : if (length <= CHACHA_BLOCK_SIZE) 77 : { 78 20 : memxor3 (c, m, x, length); 79 20 : return; 80 : } 81 20 : memxor3 (c, m, x, CHACHA_BLOCK_SIZE); 82 : 83 20 : length -= CHACHA_BLOCK_SIZE; 84 20 : c += CHACHA_BLOCK_SIZE; 85 20 : m += CHACHA_BLOCK_SIZE; 86 : } 87 : } 88 : 89 : void 90 370363 : chacha_crypt32(struct chacha_ctx *ctx, 91 : size_t length, 92 : uint8_t *c, 93 : const uint8_t *m) 94 : { 95 370363 : if (!length) 96 : return; 97 : 98 75743300 : for (;;) 99 37686500 : { 100 38056800 : uint32_t x[_CHACHA_STATE_LENGTH]; 101 : 102 38056800 : _chacha_core (x, ctx->state, CHACHA_ROUNDS); 103 : 104 38056800 : ++ctx->state[12]; 105 : 106 : /* stopping at 2^38 length per nonce is user's responsibility */ 107 : 108 38056800 : if (length <= CHACHA_BLOCK_SIZE) 109 : { 110 370363 : memxor3 (c, m, x, length); 111 370363 : return; 112 : } 113 37686500 : memxor3 (c, m, x, CHACHA_BLOCK_SIZE); 114 : 115 37686500 : length -= CHACHA_BLOCK_SIZE; 116 37686500 : c += CHACHA_BLOCK_SIZE; 117 37686500 : m += CHACHA_BLOCK_SIZE; 118 : } 119 : }