1 /* 2 * Copyright (c) 2016 Thomas Pornin <pornin@bolet.org> 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining 5 * a copy of this software and associated documentation files (the 6 * "Software"), to deal in the Software without restriction, including 7 * without limitation the rights to use, copy, modify, merge, publish, 8 * distribute, sublicense, and/or sell copies of the Software, and to 9 * permit persons to whom the Software is furnished to do so, subject to 10 * the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be 13 * included in all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 * SOFTWARE. 23 */ 24 25 #include "inner.h" 26 27 /* see bearssl_block.h */ 28 uint32_t 29 br_chacha20_ct_run(const void *key, 30 const void *iv, uint32_t cc, void *data, size_t len) 31 { 32 unsigned char *buf; 33 uint32_t kw[8], ivw[3]; 34 size_t u; 35 36 static const uint32_t CW[] = { 37 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574 38 }; 39 40 buf = data; 41 for (u = 0; u < 8; u ++) { 42 kw[u] = br_dec32le((const unsigned char *)key + (u << 2)); 43 } 44 for (u = 0; u < 3; u ++) { 45 ivw[u] = br_dec32le((const unsigned char *)iv + (u << 2)); 46 } 47 while (len > 0) { 48 uint32_t state[16]; 49 int i; 50 size_t clen; 51 unsigned char tmp[64]; 52 53 memcpy(&state[0], CW, sizeof CW); 54 memcpy(&state[4], kw, sizeof kw); 55 state[12] = cc; 56 memcpy(&state[13], ivw, sizeof ivw); 57 for (i = 0; i < 10; i ++) { 58 59 #define QROUND(a, b, c, d) do { \ 60 state[a] += state[b]; \ 61 state[d] ^= state[a]; \ 62 state[d] = (state[d] << 16) | (state[d] >> 16); \ 63 state[c] += state[d]; \ 64 state[b] ^= state[c]; \ 65 state[b] = (state[b] << 12) | (state[b] >> 20); \ 66 state[a] += state[b]; \ 67 state[d] ^= state[a]; \ 68 state[d] = (state[d] << 8) | (state[d] >> 24); \ 69 state[c] += state[d]; \ 70 state[b] ^= state[c]; \ 71 state[b] = (state[b] << 7) | (state[b] >> 25); \ 72 } while (0) 73 74 QROUND( 0, 4, 8, 12); 75 QROUND( 1, 5, 9, 13); 76 QROUND( 2, 6, 10, 14); 77 QROUND( 3, 7, 11, 15); 78 QROUND( 0, 5, 10, 15); 79 QROUND( 1, 6, 11, 12); 80 QROUND( 2, 7, 8, 13); 81 QROUND( 3, 4, 9, 14); 82 83 #undef QROUND 84 85 } 86 for (u = 0; u < 4; u ++) { 87 br_enc32le(&tmp[u << 2], state[u] + CW[u]); 88 } 89 for (u = 4; u < 12; u ++) { 90 br_enc32le(&tmp[u << 2], state[u] + kw[u - 4]); 91 } 92 br_enc32le(&tmp[48], state[12] + cc); 93 for (u = 13; u < 16; u ++) { 94 br_enc32le(&tmp[u << 2], state[u] + ivw[u - 13]); 95 } 96 97 clen = len < 64 ? len : 64; 98 for (u = 0; u < clen; u ++) { 99 buf[u] ^= tmp[u]; 100 } 101 buf += clen; 102 len -= clen; 103 cc ++; 104 } 105 return cc; 106 } 107