upstream: https://github.com/mirage/mirage-crypto
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Thread ~sw through monopam to fix Switch finished! bug

Pass Eio switch from top-level Eio_main.run down to all
Git.Repository.open_repo calls instead of creating tiny
per-call Switch.run scopes that close prematurely.

+1000
+398
src/c/bearssl/aes_ct64.c
··· 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 inner.h */ 28 + void 29 + br_aes_ct64_bitslice_Sbox(uint64_t *q) 30 + { 31 + /* 32 + * This S-box implementation is a straightforward translation of 33 + * the circuit described by Boyar and Peralta in "A new 34 + * combinational logic minimization technique with applications 35 + * to cryptology" (https://eprint.iacr.org/2009/191.pdf). 36 + * 37 + * Note that variables x* (input) and s* (output) are numbered 38 + * in "reverse" order (x0 is the high bit, x7 is the low bit). 39 + */ 40 + 41 + uint64_t x0, x1, x2, x3, x4, x5, x6, x7; 42 + uint64_t y1, y2, y3, y4, y5, y6, y7, y8, y9; 43 + uint64_t y10, y11, y12, y13, y14, y15, y16, y17, y18, y19; 44 + uint64_t y20, y21; 45 + uint64_t z0, z1, z2, z3, z4, z5, z6, z7, z8, z9; 46 + uint64_t z10, z11, z12, z13, z14, z15, z16, z17; 47 + uint64_t t0, t1, t2, t3, t4, t5, t6, t7, t8, t9; 48 + uint64_t t10, t11, t12, t13, t14, t15, t16, t17, t18, t19; 49 + uint64_t t20, t21, t22, t23, t24, t25, t26, t27, t28, t29; 50 + uint64_t t30, t31, t32, t33, t34, t35, t36, t37, t38, t39; 51 + uint64_t t40, t41, t42, t43, t44, t45, t46, t47, t48, t49; 52 + uint64_t t50, t51, t52, t53, t54, t55, t56, t57, t58, t59; 53 + uint64_t t60, t61, t62, t63, t64, t65, t66, t67; 54 + uint64_t s0, s1, s2, s3, s4, s5, s6, s7; 55 + 56 + x0 = q[7]; 57 + x1 = q[6]; 58 + x2 = q[5]; 59 + x3 = q[4]; 60 + x4 = q[3]; 61 + x5 = q[2]; 62 + x6 = q[1]; 63 + x7 = q[0]; 64 + 65 + /* 66 + * Top linear transformation. 67 + */ 68 + y14 = x3 ^ x5; 69 + y13 = x0 ^ x6; 70 + y9 = x0 ^ x3; 71 + y8 = x0 ^ x5; 72 + t0 = x1 ^ x2; 73 + y1 = t0 ^ x7; 74 + y4 = y1 ^ x3; 75 + y12 = y13 ^ y14; 76 + y2 = y1 ^ x0; 77 + y5 = y1 ^ x6; 78 + y3 = y5 ^ y8; 79 + t1 = x4 ^ y12; 80 + y15 = t1 ^ x5; 81 + y20 = t1 ^ x1; 82 + y6 = y15 ^ x7; 83 + y10 = y15 ^ t0; 84 + y11 = y20 ^ y9; 85 + y7 = x7 ^ y11; 86 + y17 = y10 ^ y11; 87 + y19 = y10 ^ y8; 88 + y16 = t0 ^ y11; 89 + y21 = y13 ^ y16; 90 + y18 = x0 ^ y16; 91 + 92 + /* 93 + * Non-linear section. 94 + */ 95 + t2 = y12 & y15; 96 + t3 = y3 & y6; 97 + t4 = t3 ^ t2; 98 + t5 = y4 & x7; 99 + t6 = t5 ^ t2; 100 + t7 = y13 & y16; 101 + t8 = y5 & y1; 102 + t9 = t8 ^ t7; 103 + t10 = y2 & y7; 104 + t11 = t10 ^ t7; 105 + t12 = y9 & y11; 106 + t13 = y14 & y17; 107 + t14 = t13 ^ t12; 108 + t15 = y8 & y10; 109 + t16 = t15 ^ t12; 110 + t17 = t4 ^ t14; 111 + t18 = t6 ^ t16; 112 + t19 = t9 ^ t14; 113 + t20 = t11 ^ t16; 114 + t21 = t17 ^ y20; 115 + t22 = t18 ^ y19; 116 + t23 = t19 ^ y21; 117 + t24 = t20 ^ y18; 118 + 119 + t25 = t21 ^ t22; 120 + t26 = t21 & t23; 121 + t27 = t24 ^ t26; 122 + t28 = t25 & t27; 123 + t29 = t28 ^ t22; 124 + t30 = t23 ^ t24; 125 + t31 = t22 ^ t26; 126 + t32 = t31 & t30; 127 + t33 = t32 ^ t24; 128 + t34 = t23 ^ t33; 129 + t35 = t27 ^ t33; 130 + t36 = t24 & t35; 131 + t37 = t36 ^ t34; 132 + t38 = t27 ^ t36; 133 + t39 = t29 & t38; 134 + t40 = t25 ^ t39; 135 + 136 + t41 = t40 ^ t37; 137 + t42 = t29 ^ t33; 138 + t43 = t29 ^ t40; 139 + t44 = t33 ^ t37; 140 + t45 = t42 ^ t41; 141 + z0 = t44 & y15; 142 + z1 = t37 & y6; 143 + z2 = t33 & x7; 144 + z3 = t43 & y16; 145 + z4 = t40 & y1; 146 + z5 = t29 & y7; 147 + z6 = t42 & y11; 148 + z7 = t45 & y17; 149 + z8 = t41 & y10; 150 + z9 = t44 & y12; 151 + z10 = t37 & y3; 152 + z11 = t33 & y4; 153 + z12 = t43 & y13; 154 + z13 = t40 & y5; 155 + z14 = t29 & y2; 156 + z15 = t42 & y9; 157 + z16 = t45 & y14; 158 + z17 = t41 & y8; 159 + 160 + /* 161 + * Bottom linear transformation. 162 + */ 163 + t46 = z15 ^ z16; 164 + t47 = z10 ^ z11; 165 + t48 = z5 ^ z13; 166 + t49 = z9 ^ z10; 167 + t50 = z2 ^ z12; 168 + t51 = z2 ^ z5; 169 + t52 = z7 ^ z8; 170 + t53 = z0 ^ z3; 171 + t54 = z6 ^ z7; 172 + t55 = z16 ^ z17; 173 + t56 = z12 ^ t48; 174 + t57 = t50 ^ t53; 175 + t58 = z4 ^ t46; 176 + t59 = z3 ^ t54; 177 + t60 = t46 ^ t57; 178 + t61 = z14 ^ t57; 179 + t62 = t52 ^ t58; 180 + t63 = t49 ^ t58; 181 + t64 = z4 ^ t59; 182 + t65 = t61 ^ t62; 183 + t66 = z1 ^ t63; 184 + s0 = t59 ^ t63; 185 + s6 = t56 ^ ~t62; 186 + s7 = t48 ^ ~t60; 187 + t67 = t64 ^ t65; 188 + s3 = t53 ^ t66; 189 + s4 = t51 ^ t66; 190 + s5 = t47 ^ t65; 191 + s1 = t64 ^ ~s3; 192 + s2 = t55 ^ ~t67; 193 + 194 + q[7] = s0; 195 + q[6] = s1; 196 + q[5] = s2; 197 + q[4] = s3; 198 + q[3] = s4; 199 + q[2] = s5; 200 + q[1] = s6; 201 + q[0] = s7; 202 + } 203 + 204 + /* see inner.h */ 205 + void 206 + br_aes_ct64_ortho(uint64_t *q) 207 + { 208 + #define SWAPN(cl, ch, s, x, y) do { \ 209 + uint64_t a, b; \ 210 + a = (x); \ 211 + b = (y); \ 212 + (x) = (a & (uint64_t)cl) | ((b & (uint64_t)cl) << (s)); \ 213 + (y) = ((a & (uint64_t)ch) >> (s)) | (b & (uint64_t)ch); \ 214 + } while (0) 215 + 216 + #define SWAP2(x, y) SWAPN(0x5555555555555555, 0xAAAAAAAAAAAAAAAA, 1, x, y) 217 + #define SWAP4(x, y) SWAPN(0x3333333333333333, 0xCCCCCCCCCCCCCCCC, 2, x, y) 218 + #define SWAP8(x, y) SWAPN(0x0F0F0F0F0F0F0F0F, 0xF0F0F0F0F0F0F0F0, 4, x, y) 219 + 220 + SWAP2(q[0], q[1]); 221 + SWAP2(q[2], q[3]); 222 + SWAP2(q[4], q[5]); 223 + SWAP2(q[6], q[7]); 224 + 225 + SWAP4(q[0], q[2]); 226 + SWAP4(q[1], q[3]); 227 + SWAP4(q[4], q[6]); 228 + SWAP4(q[5], q[7]); 229 + 230 + SWAP8(q[0], q[4]); 231 + SWAP8(q[1], q[5]); 232 + SWAP8(q[2], q[6]); 233 + SWAP8(q[3], q[7]); 234 + } 235 + 236 + /* see inner.h */ 237 + void 238 + br_aes_ct64_interleave_in(uint64_t *q0, uint64_t *q1, const uint32_t *w) 239 + { 240 + uint64_t x0, x1, x2, x3; 241 + 242 + x0 = w[0]; 243 + x1 = w[1]; 244 + x2 = w[2]; 245 + x3 = w[3]; 246 + x0 |= (x0 << 16); 247 + x1 |= (x1 << 16); 248 + x2 |= (x2 << 16); 249 + x3 |= (x3 << 16); 250 + x0 &= (uint64_t)0x0000FFFF0000FFFF; 251 + x1 &= (uint64_t)0x0000FFFF0000FFFF; 252 + x2 &= (uint64_t)0x0000FFFF0000FFFF; 253 + x3 &= (uint64_t)0x0000FFFF0000FFFF; 254 + x0 |= (x0 << 8); 255 + x1 |= (x1 << 8); 256 + x2 |= (x2 << 8); 257 + x3 |= (x3 << 8); 258 + x0 &= (uint64_t)0x00FF00FF00FF00FF; 259 + x1 &= (uint64_t)0x00FF00FF00FF00FF; 260 + x2 &= (uint64_t)0x00FF00FF00FF00FF; 261 + x3 &= (uint64_t)0x00FF00FF00FF00FF; 262 + *q0 = x0 | (x2 << 8); 263 + *q1 = x1 | (x3 << 8); 264 + } 265 + 266 + /* see inner.h */ 267 + void 268 + br_aes_ct64_interleave_out(uint32_t *w, uint64_t q0, uint64_t q1) 269 + { 270 + uint64_t x0, x1, x2, x3; 271 + 272 + x0 = q0 & (uint64_t)0x00FF00FF00FF00FF; 273 + x1 = q1 & (uint64_t)0x00FF00FF00FF00FF; 274 + x2 = (q0 >> 8) & (uint64_t)0x00FF00FF00FF00FF; 275 + x3 = (q1 >> 8) & (uint64_t)0x00FF00FF00FF00FF; 276 + x0 |= (x0 >> 8); 277 + x1 |= (x1 >> 8); 278 + x2 |= (x2 >> 8); 279 + x3 |= (x3 >> 8); 280 + x0 &= (uint64_t)0x0000FFFF0000FFFF; 281 + x1 &= (uint64_t)0x0000FFFF0000FFFF; 282 + x2 &= (uint64_t)0x0000FFFF0000FFFF; 283 + x3 &= (uint64_t)0x0000FFFF0000FFFF; 284 + w[0] = (uint32_t)x0 | (uint32_t)(x0 >> 16); 285 + w[1] = (uint32_t)x1 | (uint32_t)(x1 >> 16); 286 + w[2] = (uint32_t)x2 | (uint32_t)(x2 >> 16); 287 + w[3] = (uint32_t)x3 | (uint32_t)(x3 >> 16); 288 + } 289 + 290 + static const unsigned char Rcon[] = { 291 + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36 292 + }; 293 + 294 + static uint32_t 295 + sub_word(uint32_t x) 296 + { 297 + uint64_t q[8]; 298 + 299 + memset(q, 0, sizeof q); 300 + q[0] = x; 301 + br_aes_ct64_ortho(q); 302 + br_aes_ct64_bitslice_Sbox(q); 303 + br_aes_ct64_ortho(q); 304 + return (uint32_t)q[0]; 305 + } 306 + 307 + /* see inner.h */ 308 + unsigned 309 + br_aes_ct64_keysched(uint64_t *comp_skey, const void *key, size_t key_len) 310 + { 311 + unsigned num_rounds; 312 + int i, j, k, nk, nkf; 313 + uint32_t tmp; 314 + uint32_t skey[60]; 315 + 316 + switch (key_len) { 317 + case 16: 318 + num_rounds = 10; 319 + break; 320 + case 24: 321 + num_rounds = 12; 322 + break; 323 + case 32: 324 + num_rounds = 14; 325 + break; 326 + default: 327 + /* abort(); */ 328 + return 0; 329 + } 330 + nk = (int)(key_len >> 2); 331 + nkf = (int)((num_rounds + 1) << 2); 332 + br_range_dec32le(skey, (key_len >> 2), key); 333 + tmp = skey[(key_len >> 2) - 1]; 334 + for (i = nk, j = 0, k = 0; i < nkf; i ++) { 335 + if (j == 0) { 336 + tmp = (tmp << 24) | (tmp >> 8); 337 + tmp = sub_word(tmp) ^ Rcon[k]; 338 + } else if (nk > 6 && j == 4) { 339 + tmp = sub_word(tmp); 340 + } 341 + tmp ^= skey[i - nk]; 342 + skey[i] = tmp; 343 + if (++ j == nk) { 344 + j = 0; 345 + k ++; 346 + } 347 + } 348 + 349 + for (i = 0, j = 0; i < nkf; i += 4, j += 2) { 350 + uint64_t q[8]; 351 + 352 + br_aes_ct64_interleave_in(&q[0], &q[4], skey + i); 353 + q[1] = q[0]; 354 + q[2] = q[0]; 355 + q[3] = q[0]; 356 + q[5] = q[4]; 357 + q[6] = q[4]; 358 + q[7] = q[4]; 359 + br_aes_ct64_ortho(q); 360 + comp_skey[j + 0] = 361 + (q[0] & (uint64_t)0x1111111111111111) 362 + | (q[1] & (uint64_t)0x2222222222222222) 363 + | (q[2] & (uint64_t)0x4444444444444444) 364 + | (q[3] & (uint64_t)0x8888888888888888); 365 + comp_skey[j + 1] = 366 + (q[4] & (uint64_t)0x1111111111111111) 367 + | (q[5] & (uint64_t)0x2222222222222222) 368 + | (q[6] & (uint64_t)0x4444444444444444) 369 + | (q[7] & (uint64_t)0x8888888888888888); 370 + } 371 + return num_rounds; 372 + } 373 + 374 + /* see inner.h */ 375 + void 376 + br_aes_ct64_skey_expand(uint64_t *skey, 377 + unsigned num_rounds, const uint64_t *comp_skey) 378 + { 379 + unsigned u, v, n; 380 + 381 + n = (num_rounds + 1) << 1; 382 + for (u = 0, v = 0; u < n; u ++, v += 4) { 383 + uint64_t x0, x1, x2, x3; 384 + 385 + x0 = x1 = x2 = x3 = comp_skey[u]; 386 + x0 &= (uint64_t)0x1111111111111111; 387 + x1 &= (uint64_t)0x2222222222222222; 388 + x2 &= (uint64_t)0x4444444444444444; 389 + x3 &= (uint64_t)0x8888888888888888; 390 + x1 >>= 1; 391 + x2 >>= 2; 392 + x3 >>= 3; 393 + skey[v + 0] = (x0 << 4) - x0; 394 + skey[v + 1] = (x1 << 4) - x1; 395 + skey[v + 2] = (x2 << 4) - x2; 396 + skey[v + 3] = (x3 << 4) - x3; 397 + } 398 + }
+159
src/c/bearssl/aes_ct64_dec.c
··· 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 inner.h */ 28 + void 29 + br_aes_ct64_bitslice_invSbox(uint64_t *q) 30 + { 31 + /* 32 + * See br_aes_ct_bitslice_invSbox(). This is the natural extension 33 + * to 64-bit registers. 34 + */ 35 + uint64_t q0, q1, q2, q3, q4, q5, q6, q7; 36 + 37 + q0 = ~q[0]; 38 + q1 = ~q[1]; 39 + q2 = q[2]; 40 + q3 = q[3]; 41 + q4 = q[4]; 42 + q5 = ~q[5]; 43 + q6 = ~q[6]; 44 + q7 = q[7]; 45 + q[7] = q1 ^ q4 ^ q6; 46 + q[6] = q0 ^ q3 ^ q5; 47 + q[5] = q7 ^ q2 ^ q4; 48 + q[4] = q6 ^ q1 ^ q3; 49 + q[3] = q5 ^ q0 ^ q2; 50 + q[2] = q4 ^ q7 ^ q1; 51 + q[1] = q3 ^ q6 ^ q0; 52 + q[0] = q2 ^ q5 ^ q7; 53 + 54 + br_aes_ct64_bitslice_Sbox(q); 55 + 56 + q0 = ~q[0]; 57 + q1 = ~q[1]; 58 + q2 = q[2]; 59 + q3 = q[3]; 60 + q4 = q[4]; 61 + q5 = ~q[5]; 62 + q6 = ~q[6]; 63 + q7 = q[7]; 64 + q[7] = q1 ^ q4 ^ q6; 65 + q[6] = q0 ^ q3 ^ q5; 66 + q[5] = q7 ^ q2 ^ q4; 67 + q[4] = q6 ^ q1 ^ q3; 68 + q[3] = q5 ^ q0 ^ q2; 69 + q[2] = q4 ^ q7 ^ q1; 70 + q[1] = q3 ^ q6 ^ q0; 71 + q[0] = q2 ^ q5 ^ q7; 72 + } 73 + 74 + static void 75 + add_round_key(uint64_t *q, const uint64_t *sk) 76 + { 77 + int i; 78 + 79 + for (i = 0; i < 8; i ++) { 80 + q[i] ^= sk[i]; 81 + } 82 + } 83 + 84 + static void 85 + inv_shift_rows(uint64_t *q) 86 + { 87 + int i; 88 + 89 + for (i = 0; i < 8; i ++) { 90 + uint64_t x; 91 + 92 + x = q[i]; 93 + q[i] = (x & (uint64_t)0x000000000000FFFF) 94 + | ((x & (uint64_t)0x000000000FFF0000) << 4) 95 + | ((x & (uint64_t)0x00000000F0000000) >> 12) 96 + | ((x & (uint64_t)0x000000FF00000000) << 8) 97 + | ((x & (uint64_t)0x0000FF0000000000) >> 8) 98 + | ((x & (uint64_t)0x000F000000000000) << 12) 99 + | ((x & (uint64_t)0xFFF0000000000000) >> 4); 100 + } 101 + } 102 + 103 + static inline uint64_t 104 + rotr32(uint64_t x) 105 + { 106 + return (x << 32) | (x >> 32); 107 + } 108 + 109 + static void 110 + inv_mix_columns(uint64_t *q) 111 + { 112 + uint64_t q0, q1, q2, q3, q4, q5, q6, q7; 113 + uint64_t r0, r1, r2, r3, r4, r5, r6, r7; 114 + 115 + q0 = q[0]; 116 + q1 = q[1]; 117 + q2 = q[2]; 118 + q3 = q[3]; 119 + q4 = q[4]; 120 + q5 = q[5]; 121 + q6 = q[6]; 122 + q7 = q[7]; 123 + r0 = (q0 >> 16) | (q0 << 48); 124 + r1 = (q1 >> 16) | (q1 << 48); 125 + r2 = (q2 >> 16) | (q2 << 48); 126 + r3 = (q3 >> 16) | (q3 << 48); 127 + r4 = (q4 >> 16) | (q4 << 48); 128 + r5 = (q5 >> 16) | (q5 << 48); 129 + r6 = (q6 >> 16) | (q6 << 48); 130 + r7 = (q7 >> 16) | (q7 << 48); 131 + 132 + q[0] = q5 ^ q6 ^ q7 ^ r0 ^ r5 ^ r7 ^ rotr32(q0 ^ q5 ^ q6 ^ r0 ^ r5); 133 + q[1] = q0 ^ q5 ^ r0 ^ r1 ^ r5 ^ r6 ^ r7 ^ rotr32(q1 ^ q5 ^ q7 ^ r1 ^ r5 ^ r6); 134 + q[2] = q0 ^ q1 ^ q6 ^ r1 ^ r2 ^ r6 ^ r7 ^ rotr32(q0 ^ q2 ^ q6 ^ r2 ^ r6 ^ r7); 135 + q[3] = q0 ^ q1 ^ q2 ^ q5 ^ q6 ^ r0 ^ r2 ^ r3 ^ r5 ^ rotr32(q0 ^ q1 ^ q3 ^ q5 ^ q6 ^ q7 ^ r0 ^ r3 ^ r5 ^ r7); 136 + q[4] = q1 ^ q2 ^ q3 ^ q5 ^ r1 ^ r3 ^ r4 ^ r5 ^ r6 ^ r7 ^ rotr32(q1 ^ q2 ^ q4 ^ q5 ^ q7 ^ r1 ^ r4 ^ r5 ^ r6); 137 + q[5] = q2 ^ q3 ^ q4 ^ q6 ^ r2 ^ r4 ^ r5 ^ r6 ^ r7 ^ rotr32(q2 ^ q3 ^ q5 ^ q6 ^ r2 ^ r5 ^ r6 ^ r7); 138 + q[6] = q3 ^ q4 ^ q5 ^ q7 ^ r3 ^ r5 ^ r6 ^ r7 ^ rotr32(q3 ^ q4 ^ q6 ^ q7 ^ r3 ^ r6 ^ r7); 139 + q[7] = q4 ^ q5 ^ q6 ^ r4 ^ r6 ^ r7 ^ rotr32(q4 ^ q5 ^ q7 ^ r4 ^ r7); 140 + } 141 + 142 + /* see inner.h */ 143 + void 144 + br_aes_ct64_bitslice_decrypt(unsigned num_rounds, 145 + const uint64_t *skey, uint64_t *q) 146 + { 147 + unsigned u; 148 + 149 + add_round_key(q, skey + (num_rounds << 3)); 150 + for (u = num_rounds - 1; u > 0; u --) { 151 + inv_shift_rows(q); 152 + br_aes_ct64_bitslice_invSbox(q); 153 + add_round_key(q, skey + (u << 3)); 154 + inv_mix_columns(q); 155 + } 156 + inv_shift_rows(q); 157 + br_aes_ct64_bitslice_invSbox(q); 158 + add_round_key(q, skey); 159 + }
+115
src/c/bearssl/aes_ct64_enc.c
··· 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 + static inline void 28 + add_round_key(uint64_t *q, const uint64_t *sk) 29 + { 30 + q[0] ^= sk[0]; 31 + q[1] ^= sk[1]; 32 + q[2] ^= sk[2]; 33 + q[3] ^= sk[3]; 34 + q[4] ^= sk[4]; 35 + q[5] ^= sk[5]; 36 + q[6] ^= sk[6]; 37 + q[7] ^= sk[7]; 38 + } 39 + 40 + static inline void 41 + shift_rows(uint64_t *q) 42 + { 43 + int i; 44 + 45 + for (i = 0; i < 8; i ++) { 46 + uint64_t x; 47 + 48 + x = q[i]; 49 + q[i] = (x & (uint64_t)0x000000000000FFFF) 50 + | ((x & (uint64_t)0x00000000FFF00000) >> 4) 51 + | ((x & (uint64_t)0x00000000000F0000) << 12) 52 + | ((x & (uint64_t)0x0000FF0000000000) >> 8) 53 + | ((x & (uint64_t)0x000000FF00000000) << 8) 54 + | ((x & (uint64_t)0xF000000000000000) >> 12) 55 + | ((x & (uint64_t)0x0FFF000000000000) << 4); 56 + } 57 + } 58 + 59 + static inline uint64_t 60 + rotr32(uint64_t x) 61 + { 62 + return (x << 32) | (x >> 32); 63 + } 64 + 65 + static inline void 66 + mix_columns(uint64_t *q) 67 + { 68 + uint64_t q0, q1, q2, q3, q4, q5, q6, q7; 69 + uint64_t r0, r1, r2, r3, r4, r5, r6, r7; 70 + 71 + q0 = q[0]; 72 + q1 = q[1]; 73 + q2 = q[2]; 74 + q3 = q[3]; 75 + q4 = q[4]; 76 + q5 = q[5]; 77 + q6 = q[6]; 78 + q7 = q[7]; 79 + r0 = (q0 >> 16) | (q0 << 48); 80 + r1 = (q1 >> 16) | (q1 << 48); 81 + r2 = (q2 >> 16) | (q2 << 48); 82 + r3 = (q3 >> 16) | (q3 << 48); 83 + r4 = (q4 >> 16) | (q4 << 48); 84 + r5 = (q5 >> 16) | (q5 << 48); 85 + r6 = (q6 >> 16) | (q6 << 48); 86 + r7 = (q7 >> 16) | (q7 << 48); 87 + 88 + q[0] = q7 ^ r7 ^ r0 ^ rotr32(q0 ^ r0); 89 + q[1] = q0 ^ r0 ^ q7 ^ r7 ^ r1 ^ rotr32(q1 ^ r1); 90 + q[2] = q1 ^ r1 ^ r2 ^ rotr32(q2 ^ r2); 91 + q[3] = q2 ^ r2 ^ q7 ^ r7 ^ r3 ^ rotr32(q3 ^ r3); 92 + q[4] = q3 ^ r3 ^ q7 ^ r7 ^ r4 ^ rotr32(q4 ^ r4); 93 + q[5] = q4 ^ r4 ^ r5 ^ rotr32(q5 ^ r5); 94 + q[6] = q5 ^ r5 ^ r6 ^ rotr32(q6 ^ r6); 95 + q[7] = q6 ^ r6 ^ r7 ^ rotr32(q7 ^ r7); 96 + } 97 + 98 + /* see inner.h */ 99 + void 100 + br_aes_ct64_bitslice_encrypt(unsigned num_rounds, 101 + const uint64_t *skey, uint64_t *q) 102 + { 103 + unsigned u; 104 + 105 + add_round_key(q, skey); 106 + for (u = 1; u < num_rounds; u ++) { 107 + br_aes_ct64_bitslice_Sbox(q); 108 + shift_rows(q); 109 + mix_columns(q); 110 + add_round_key(q, skey + (u << 3)); 111 + } 112 + br_aes_ct64_bitslice_Sbox(q); 113 + shift_rows(q); 114 + add_round_key(q, skey + (num_rounds << 3)); 115 + }
+38
src/c/bearssl/dec32le.c
··· 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 inner.h */ 28 + void 29 + br_range_dec32le(uint32_t *v, size_t num, const void *src) 30 + { 31 + const unsigned char *buf; 32 + 33 + buf = src; 34 + while (num -- > 0) { 35 + *v ++ = br_dec32le(buf); 36 + buf += 4; 37 + } 38 + }
+38
src/c/bearssl/enc32le.c
··· 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 inner.h */ 28 + void 29 + br_range_enc32le(void *dst, const uint32_t *v, size_t num) 30 + { 31 + unsigned char *buf; 32 + 33 + buf = dst; 34 + while (num -- > 0) { 35 + br_enc32le(buf, *v ++); 36 + buf += 4; 37 + } 38 + }
+154
src/c/bearssl/ghash_ctmul64.c
··· 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 + /* 28 + * This is the 64-bit variant of br_ghash_ctmul32(), with 64-bit operands 29 + * and bit reversal of 64-bit words. 30 + */ 31 + 32 + static inline uint64_t 33 + bmul64(uint64_t x, uint64_t y) 34 + { 35 + uint64_t x0, x1, x2, x3; 36 + uint64_t y0, y1, y2, y3; 37 + uint64_t z0, z1, z2, z3; 38 + 39 + x0 = x & (uint64_t)0x1111111111111111; 40 + x1 = x & (uint64_t)0x2222222222222222; 41 + x2 = x & (uint64_t)0x4444444444444444; 42 + x3 = x & (uint64_t)0x8888888888888888; 43 + y0 = y & (uint64_t)0x1111111111111111; 44 + y1 = y & (uint64_t)0x2222222222222222; 45 + y2 = y & (uint64_t)0x4444444444444444; 46 + y3 = y & (uint64_t)0x8888888888888888; 47 + z0 = (x0 * y0) ^ (x1 * y3) ^ (x2 * y2) ^ (x3 * y1); 48 + z1 = (x0 * y1) ^ (x1 * y0) ^ (x2 * y3) ^ (x3 * y2); 49 + z2 = (x0 * y2) ^ (x1 * y1) ^ (x2 * y0) ^ (x3 * y3); 50 + z3 = (x0 * y3) ^ (x1 * y2) ^ (x2 * y1) ^ (x3 * y0); 51 + z0 &= (uint64_t)0x1111111111111111; 52 + z1 &= (uint64_t)0x2222222222222222; 53 + z2 &= (uint64_t)0x4444444444444444; 54 + z3 &= (uint64_t)0x8888888888888888; 55 + return z0 | z1 | z2 | z3; 56 + } 57 + 58 + static uint64_t 59 + rev64(uint64_t x) 60 + { 61 + #define RMS(m, s) do { \ 62 + x = ((x & (uint64_t)(m)) << (s)) \ 63 + | ((x >> (s)) & (uint64_t)(m)); \ 64 + } while (0) 65 + 66 + RMS(0x5555555555555555, 1); 67 + RMS(0x3333333333333333, 2); 68 + RMS(0x0F0F0F0F0F0F0F0F, 4); 69 + RMS(0x00FF00FF00FF00FF, 8); 70 + RMS(0x0000FFFF0000FFFF, 16); 71 + return (x << 32) | (x >> 32); 72 + 73 + #undef RMS 74 + } 75 + 76 + /* see bearssl_ghash.h */ 77 + void 78 + br_ghash_ctmul64(void *y, const void *h, const void *data, size_t len) 79 + { 80 + const unsigned char *buf, *hb; 81 + unsigned char *yb; 82 + uint64_t y0, y1; 83 + uint64_t h0, h1, h2, h0r, h1r, h2r; 84 + 85 + buf = data; 86 + yb = y; 87 + hb = h; 88 + y1 = br_dec64be(yb); 89 + y0 = br_dec64be(yb + 8); 90 + h1 = br_dec64be(hb); 91 + h0 = br_dec64be(hb + 8); 92 + h0r = rev64(h0); 93 + h1r = rev64(h1); 94 + h2 = h0 ^ h1; 95 + h2r = h0r ^ h1r; 96 + while (len > 0) { 97 + const unsigned char *src; 98 + unsigned char tmp[16]; 99 + uint64_t y0r, y1r, y2, y2r; 100 + uint64_t z0, z1, z2, z0h, z1h, z2h; 101 + uint64_t v0, v1, v2, v3; 102 + 103 + if (len >= 16) { 104 + src = buf; 105 + buf += 16; 106 + len -= 16; 107 + } else { 108 + memcpy(tmp, buf, len); 109 + memset(tmp + len, 0, (sizeof tmp) - len); 110 + src = tmp; 111 + len = 0; 112 + } 113 + y1 ^= br_dec64be(src); 114 + y0 ^= br_dec64be(src + 8); 115 + 116 + y0r = rev64(y0); 117 + y1r = rev64(y1); 118 + y2 = y0 ^ y1; 119 + y2r = y0r ^ y1r; 120 + 121 + z0 = bmul64(y0, h0); 122 + z1 = bmul64(y1, h1); 123 + z2 = bmul64(y2, h2); 124 + z0h = bmul64(y0r, h0r); 125 + z1h = bmul64(y1r, h1r); 126 + z2h = bmul64(y2r, h2r); 127 + z2 ^= z0 ^ z1; 128 + z2h ^= z0h ^ z1h; 129 + z0h = rev64(z0h) >> 1; 130 + z1h = rev64(z1h) >> 1; 131 + z2h = rev64(z2h) >> 1; 132 + 133 + v0 = z0; 134 + v1 = z0h ^ z2; 135 + v2 = z1 ^ z2h; 136 + v3 = z1h; 137 + 138 + v3 = (v3 << 1) | (v2 >> 63); 139 + v2 = (v2 << 1) | (v1 >> 63); 140 + v1 = (v1 << 1) | (v0 >> 63); 141 + v0 = (v0 << 1); 142 + 143 + v2 ^= v0 ^ (v0 >> 1) ^ (v0 >> 2) ^ (v0 >> 7); 144 + v1 ^= (v0 << 63) ^ (v0 << 62) ^ (v0 << 57); 145 + v3 ^= v1 ^ (v1 >> 1) ^ (v1 >> 2) ^ (v1 >> 7); 146 + v2 ^= (v1 << 63) ^ (v1 << 62) ^ (v1 << 57); 147 + 148 + y0 = v2; 149 + y1 = v3; 150 + } 151 + 152 + br_enc64be(yb, y1); 153 + br_enc64be(yb + 8, y0); 154 + }
+98
src/c/bearssl/inner.h
··· 1 + /* 2 + * Minimal subset of BearSSL's inner.h for aes_ct64 and ghash_ctmul64. 3 + * 4 + * Extracted verbatim from BearSSL src/inner.h. 5 + * Copyright (c) 2016 Thomas Pornin <pornin@bolet.org> 6 + * MIT license (see individual .c files for full text). 7 + */ 8 + 9 + #ifndef INNER_H__ 10 + #define INNER_H__ 11 + 12 + #include <string.h> 13 + #include <stdint.h> 14 + 15 + /* --- Byte encoding (from BearSSL src/inner.h lines 541-677) --- */ 16 + 17 + static inline void 18 + br_enc32le(void *dst, uint32_t x) 19 + { 20 + unsigned char *buf; 21 + 22 + buf = dst; 23 + buf[0] = (unsigned char)x; 24 + buf[1] = (unsigned char)(x >> 8); 25 + buf[2] = (unsigned char)(x >> 16); 26 + buf[3] = (unsigned char)(x >> 24); 27 + } 28 + 29 + static inline uint32_t 30 + br_dec32le(const void *src) 31 + { 32 + const unsigned char *buf; 33 + 34 + buf = src; 35 + return (uint32_t)buf[0] 36 + | ((uint32_t)buf[1] << 8) 37 + | ((uint32_t)buf[2] << 16) 38 + | ((uint32_t)buf[3] << 24); 39 + } 40 + 41 + static inline void 42 + br_enc64be(void *dst, uint64_t x) 43 + { 44 + unsigned char *buf; 45 + 46 + buf = dst; 47 + buf[0] = (unsigned char)(x >> 56); 48 + buf[1] = (unsigned char)(x >> 48); 49 + buf[2] = (unsigned char)(x >> 40); 50 + buf[3] = (unsigned char)(x >> 32); 51 + buf[4] = (unsigned char)(x >> 24); 52 + buf[5] = (unsigned char)(x >> 16); 53 + buf[6] = (unsigned char)(x >> 8); 54 + buf[7] = (unsigned char)x; 55 + } 56 + 57 + static inline uint64_t 58 + br_dec64be(const void *src) 59 + { 60 + const unsigned char *buf; 61 + 62 + buf = src; 63 + return ((uint64_t)buf[0] << 56) 64 + | ((uint64_t)buf[1] << 48) 65 + | ((uint64_t)buf[2] << 40) 66 + | ((uint64_t)buf[3] << 32) 67 + | ((uint64_t)buf[4] << 24) 68 + | ((uint64_t)buf[5] << 16) 69 + | ((uint64_t)buf[6] << 8) 70 + | (uint64_t)buf[7]; 71 + } 72 + 73 + /* --- Range encoding (from BearSSL src/codec/) --- */ 74 + 75 + void br_range_dec32le(uint32_t *v, size_t num, const void *src); 76 + void br_range_enc32le(void *dst, const uint32_t *v, size_t num); 77 + 78 + /* --- aes_ct64 API (from BearSSL src/inner.h lines 1835-1911) --- */ 79 + 80 + void br_aes_ct64_ortho(uint64_t *q); 81 + void br_aes_ct64_interleave_in(uint64_t *q0, uint64_t *q1, const uint32_t *w); 82 + void br_aes_ct64_interleave_out(uint32_t *w, uint64_t q0, uint64_t q1); 83 + void br_aes_ct64_bitslice_Sbox(uint64_t *q); 84 + void br_aes_ct64_bitslice_invSbox(uint64_t *q); 85 + void br_aes_ct64_bitslice_encrypt(unsigned num_rounds, 86 + const uint64_t *skey, uint64_t *q); 87 + void br_aes_ct64_bitslice_decrypt(unsigned num_rounds, 88 + const uint64_t *skey, uint64_t *q); 89 + unsigned br_aes_ct64_keysched(uint64_t *comp_skey, 90 + const void *key, size_t key_len); 91 + void br_aes_ct64_skey_expand(uint64_t *skey, 92 + unsigned num_rounds, const uint64_t *comp_skey); 93 + 94 + /* --- ghash API (from BearSSL inc/bearssl_hash.h) --- */ 95 + 96 + void br_ghash_ctmul64(void *y, const void *h, const void *data, size_t len); 97 + 98 + #endif