| 1 |
/* Imported via OpenSSH-7.6p1, TeraTerm Project doda */ |
| 2 |
|
| 3 |
/* |
| 4 |
chacha-merged.c version 20080118 |
| 5 |
D. J. Bernstein |
| 6 |
Public domain. |
| 7 |
*/ |
| 8 |
|
| 9 |
// #include "includes.h" |
| 10 |
|
| 11 |
/* |
| 12 |
* このソースは OpenSSL のときだけ使われる |
| 13 |
* LibreSSL のときは libressl/crypto/compat/chacha_private.h が使われる |
| 14 |
*/ |
| 15 |
#include <openssl/opensslv.h> /* For OPENSSL_VERSION_NUMBER */ |
| 16 |
#ifndef LIBRESSL_VERSION_NUMBER |
| 17 |
|
| 18 |
#include "chacha.h" |
| 19 |
|
| 20 |
/* $OpenBSD: chacha.c,v 1.1 2013/11/21 00:45:44 djm Exp $ */ |
| 21 |
|
| 22 |
typedef unsigned char u8; |
| 23 |
typedef unsigned int u32; |
| 24 |
|
| 25 |
typedef struct chacha_ctx chacha_ctx; |
| 26 |
|
| 27 |
#define U8C(v) (v##U) |
| 28 |
#define U32C(v) (v##U) |
| 29 |
|
| 30 |
#define U8V(v) ((u8)(v) & U8C(0xFF)) |
| 31 |
#define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF)) |
| 32 |
|
| 33 |
#define ROTL32(v, n) \ |
| 34 |
(U32V((v) << (n)) | ((v) >> (32 - (n)))) |
| 35 |
|
| 36 |
#define U8TO32_LITTLE(p) \ |
| 37 |
(((u32)((p)[0]) ) | \ |
| 38 |
((u32)((p)[1]) << 8) | \ |
| 39 |
((u32)((p)[2]) << 16) | \ |
| 40 |
((u32)((p)[3]) << 24)) |
| 41 |
|
| 42 |
#define U32TO8_LITTLE(p, v) \ |
| 43 |
do { \ |
| 44 |
(p)[0] = U8V((v) ); \ |
| 45 |
(p)[1] = U8V((v) >> 8); \ |
| 46 |
(p)[2] = U8V((v) >> 16); \ |
| 47 |
(p)[3] = U8V((v) >> 24); \ |
| 48 |
} while (0) |
| 49 |
|
| 50 |
#define ROTATE(v,c) (ROTL32(v,c)) |
| 51 |
#define XOR(v,w) ((v) ^ (w)) |
| 52 |
#define PLUS(v,w) (U32V((v) + (w))) |
| 53 |
#define PLUSONE(v) (PLUS((v),1)) |
| 54 |
|
| 55 |
#define QUARTERROUND(a,b,c,d) \ |
| 56 |
a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \ |
| 57 |
c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \ |
| 58 |
a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \ |
| 59 |
c = PLUS(c,d); b = ROTATE(XOR(b,c), 7); |
| 60 |
|
| 61 |
static const char sigma[16] = "expand 32-byte k"; |
| 62 |
static const char tau[16] = "expand 16-byte k"; |
| 63 |
|
| 64 |
void |
| 65 |
chacha_keysetup(chacha_ctx *x, const u8 *k, u32 kbits) |
| 66 |
{ |
| 67 |
const char *constants; |
| 68 |
|
| 69 |
x->input[4] = U8TO32_LITTLE(k + 0); |
| 70 |
x->input[5] = U8TO32_LITTLE(k + 4); |
| 71 |
x->input[6] = U8TO32_LITTLE(k + 8); |
| 72 |
x->input[7] = U8TO32_LITTLE(k + 12); |
| 73 |
if (kbits == 256) { /* recommended */ |
| 74 |
k += 16; |
| 75 |
constants = sigma; |
| 76 |
} else { /* kbits == 128 */ |
| 77 |
constants = tau; |
| 78 |
} |
| 79 |
x->input[8] = U8TO32_LITTLE(k + 0); |
| 80 |
x->input[9] = U8TO32_LITTLE(k + 4); |
| 81 |
x->input[10] = U8TO32_LITTLE(k + 8); |
| 82 |
x->input[11] = U8TO32_LITTLE(k + 12); |
| 83 |
x->input[0] = U8TO32_LITTLE(constants + 0); |
| 84 |
x->input[1] = U8TO32_LITTLE(constants + 4); |
| 85 |
x->input[2] = U8TO32_LITTLE(constants + 8); |
| 86 |
x->input[3] = U8TO32_LITTLE(constants + 12); |
| 87 |
} |
| 88 |
|
| 89 |
void |
| 90 |
chacha_ivsetup(chacha_ctx *x, const u8 *iv, const u8 *counter) |
| 91 |
{ |
| 92 |
x->input[12] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 0); |
| 93 |
x->input[13] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 4); |
| 94 |
x->input[14] = U8TO32_LITTLE(iv + 0); |
| 95 |
x->input[15] = U8TO32_LITTLE(iv + 4); |
| 96 |
} |
| 97 |
|
| 98 |
void |
| 99 |
chacha_encrypt_bytes(chacha_ctx *x, const u8 *m, u8 *c, u32 bytes) |
| 100 |
{ |
| 101 |
u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; |
| 102 |
u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15; |
| 103 |
u8 *ctarget = NULL; |
| 104 |
u8 tmp[64]; |
| 105 |
u_int i; |
| 106 |
|
| 107 |
if (!bytes) return; |
| 108 |
|
| 109 |
j0 = x->input[0]; |
| 110 |
j1 = x->input[1]; |
| 111 |
j2 = x->input[2]; |
| 112 |
j3 = x->input[3]; |
| 113 |
j4 = x->input[4]; |
| 114 |
j5 = x->input[5]; |
| 115 |
j6 = x->input[6]; |
| 116 |
j7 = x->input[7]; |
| 117 |
j8 = x->input[8]; |
| 118 |
j9 = x->input[9]; |
| 119 |
j10 = x->input[10]; |
| 120 |
j11 = x->input[11]; |
| 121 |
j12 = x->input[12]; |
| 122 |
j13 = x->input[13]; |
| 123 |
j14 = x->input[14]; |
| 124 |
j15 = x->input[15]; |
| 125 |
|
| 126 |
for (;;) { |
| 127 |
if (bytes < 64) { |
| 128 |
for (i = 0;i < bytes;++i) tmp[i] = m[i]; |
| 129 |
m = tmp; |
| 130 |
ctarget = c; |
| 131 |
c = tmp; |
| 132 |
} |
| 133 |
x0 = j0; |
| 134 |
x1 = j1; |
| 135 |
x2 = j2; |
| 136 |
x3 = j3; |
| 137 |
x4 = j4; |
| 138 |
x5 = j5; |
| 139 |
x6 = j6; |
| 140 |
x7 = j7; |
| 141 |
x8 = j8; |
| 142 |
x9 = j9; |
| 143 |
x10 = j10; |
| 144 |
x11 = j11; |
| 145 |
x12 = j12; |
| 146 |
x13 = j13; |
| 147 |
x14 = j14; |
| 148 |
x15 = j15; |
| 149 |
for (i = 20;i > 0;i -= 2) { |
| 150 |
QUARTERROUND( x0, x4, x8,x12) |
| 151 |
QUARTERROUND( x1, x5, x9,x13) |
| 152 |
QUARTERROUND( x2, x6,x10,x14) |
| 153 |
QUARTERROUND( x3, x7,x11,x15) |
| 154 |
QUARTERROUND( x0, x5,x10,x15) |
| 155 |
QUARTERROUND( x1, x6,x11,x12) |
| 156 |
QUARTERROUND( x2, x7, x8,x13) |
| 157 |
QUARTERROUND( x3, x4, x9,x14) |
| 158 |
} |
| 159 |
x0 = PLUS(x0,j0); |
| 160 |
x1 = PLUS(x1,j1); |
| 161 |
x2 = PLUS(x2,j2); |
| 162 |
x3 = PLUS(x3,j3); |
| 163 |
x4 = PLUS(x4,j4); |
| 164 |
x5 = PLUS(x5,j5); |
| 165 |
x6 = PLUS(x6,j6); |
| 166 |
x7 = PLUS(x7,j7); |
| 167 |
x8 = PLUS(x8,j8); |
| 168 |
x9 = PLUS(x9,j9); |
| 169 |
x10 = PLUS(x10,j10); |
| 170 |
x11 = PLUS(x11,j11); |
| 171 |
x12 = PLUS(x12,j12); |
| 172 |
x13 = PLUS(x13,j13); |
| 173 |
x14 = PLUS(x14,j14); |
| 174 |
x15 = PLUS(x15,j15); |
| 175 |
|
| 176 |
x0 = XOR(x0,U8TO32_LITTLE(m + 0)); |
| 177 |
x1 = XOR(x1,U8TO32_LITTLE(m + 4)); |
| 178 |
x2 = XOR(x2,U8TO32_LITTLE(m + 8)); |
| 179 |
x3 = XOR(x3,U8TO32_LITTLE(m + 12)); |
| 180 |
x4 = XOR(x4,U8TO32_LITTLE(m + 16)); |
| 181 |
x5 = XOR(x5,U8TO32_LITTLE(m + 20)); |
| 182 |
x6 = XOR(x6,U8TO32_LITTLE(m + 24)); |
| 183 |
x7 = XOR(x7,U8TO32_LITTLE(m + 28)); |
| 184 |
x8 = XOR(x8,U8TO32_LITTLE(m + 32)); |
| 185 |
x9 = XOR(x9,U8TO32_LITTLE(m + 36)); |
| 186 |
x10 = XOR(x10,U8TO32_LITTLE(m + 40)); |
| 187 |
x11 = XOR(x11,U8TO32_LITTLE(m + 44)); |
| 188 |
x12 = XOR(x12,U8TO32_LITTLE(m + 48)); |
| 189 |
x13 = XOR(x13,U8TO32_LITTLE(m + 52)); |
| 190 |
x14 = XOR(x14,U8TO32_LITTLE(m + 56)); |
| 191 |
x15 = XOR(x15,U8TO32_LITTLE(m + 60)); |
| 192 |
|
| 193 |
j12 = PLUSONE(j12); |
| 194 |
if (!j12) { |
| 195 |
j13 = PLUSONE(j13); |
| 196 |
/* stopping at 2^70 bytes per nonce is user's responsibility */ |
| 197 |
} |
| 198 |
|
| 199 |
U32TO8_LITTLE(c + 0,x0); |
| 200 |
U32TO8_LITTLE(c + 4,x1); |
| 201 |
U32TO8_LITTLE(c + 8,x2); |
| 202 |
U32TO8_LITTLE(c + 12,x3); |
| 203 |
U32TO8_LITTLE(c + 16,x4); |
| 204 |
U32TO8_LITTLE(c + 20,x5); |
| 205 |
U32TO8_LITTLE(c + 24,x6); |
| 206 |
U32TO8_LITTLE(c + 28,x7); |
| 207 |
U32TO8_LITTLE(c + 32,x8); |
| 208 |
U32TO8_LITTLE(c + 36,x9); |
| 209 |
U32TO8_LITTLE(c + 40,x10); |
| 210 |
U32TO8_LITTLE(c + 44,x11); |
| 211 |
U32TO8_LITTLE(c + 48,x12); |
| 212 |
U32TO8_LITTLE(c + 52,x13); |
| 213 |
U32TO8_LITTLE(c + 56,x14); |
| 214 |
U32TO8_LITTLE(c + 60,x15); |
| 215 |
|
| 216 |
if (bytes <= 64) { |
| 217 |
if (bytes < 64) { |
| 218 |
for (i = 0;i < bytes;++i) ctarget[i] = c[i]; |
| 219 |
} |
| 220 |
x->input[12] = j12; |
| 221 |
x->input[13] = j13; |
| 222 |
return; |
| 223 |
} |
| 224 |
bytes -= 64; |
| 225 |
c += 64; |
| 226 |
m += 64; |
| 227 |
} |
| 228 |
} |
| 229 |
|
| 230 |
#endif /* LIBRESSL_VERSION_NUMBER */ |