1 1.2 jmcneill /* $NetBSD: blake2s.c,v 1.2 2021/10/17 14:45:45 jmcneill Exp $ */ 2 1.1 riastrad 3 1.1 riastrad /*- 4 1.1 riastrad * Copyright (c) 2015 Taylor R. Campbell 5 1.1 riastrad * All rights reserved. 6 1.1 riastrad * 7 1.1 riastrad * Redistribution and use in source and binary forms, with or without 8 1.1 riastrad * modification, are permitted provided that the following conditions 9 1.1 riastrad * are met: 10 1.1 riastrad * 1. Redistributions of source code must retain the above copyright 11 1.1 riastrad * notice, this list of conditions and the following disclaimer. 12 1.1 riastrad * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 riastrad * notice, this list of conditions and the following disclaimer in the 14 1.1 riastrad * documentation and/or other materials provided with the distribution. 15 1.1 riastrad * 16 1.1 riastrad * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 1.1 riastrad * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 1.1 riastrad * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 1.1 riastrad * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 1.1 riastrad * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 1.1 riastrad * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 1.1 riastrad * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 1.1 riastrad * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 1.1 riastrad * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 1.1 riastrad * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 1.1 riastrad * SUCH DAMAGE. 27 1.1 riastrad */ 28 1.1 riastrad 29 1.1 riastrad #ifdef _KERNEL 30 1.1 riastrad 31 1.1 riastrad #include <sys/cdefs.h> 32 1.2 jmcneill __KERNEL_RCSID(0, "$NetBSD: blake2s.c,v 1.2 2021/10/17 14:45:45 jmcneill Exp $"); 33 1.1 riastrad 34 1.1 riastrad #include <sys/types.h> 35 1.1 riastrad #include <sys/module.h> 36 1.1 riastrad 37 1.1 riastrad #include <lib/libkern/libkern.h> 38 1.1 riastrad 39 1.1 riastrad #else 40 1.1 riastrad 41 1.1 riastrad #define _POSIX_C_SOURCE 200809L 42 1.1 riastrad 43 1.1 riastrad #include <assert.h> 44 1.1 riastrad #include <stdint.h> 45 1.1 riastrad #include <string.h> 46 1.1 riastrad 47 1.1 riastrad #endif 48 1.1 riastrad 49 1.1 riastrad #include "blake2s.h" 50 1.1 riastrad 51 1.1 riastrad #include <sys/endian.h> 52 1.1 riastrad 53 1.1 riastrad static inline uint32_t 54 1.1 riastrad rotr32(uint32_t x, unsigned c) 55 1.1 riastrad { 56 1.1 riastrad 57 1.1 riastrad return ((x >> c) | (x << (32 - c))); 58 1.1 riastrad } 59 1.1 riastrad 60 1.1 riastrad #define BLAKE2S_G(VA, VB, VC, VD, X, Y) do \ 61 1.1 riastrad { \ 62 1.1 riastrad (VA) = (VA) + (VB) + (X); \ 63 1.1 riastrad (VD) = rotr32((VD) ^ (VA), 16); \ 64 1.1 riastrad (VC) = (VC) + (VD); \ 65 1.1 riastrad (VB) = rotr32((VB) ^ (VC), 12); \ 66 1.1 riastrad (VA) = (VA) + (VB) + (Y); \ 67 1.1 riastrad (VD) = rotr32((VD) ^ (VA), 8); \ 68 1.1 riastrad (VC) = (VC) + (VD); \ 69 1.1 riastrad (VB) = rotr32((VB) ^ (VC), 7); \ 70 1.1 riastrad } while (0) 71 1.1 riastrad 72 1.1 riastrad static const uint32_t blake2s_iv[8] = { 73 1.1 riastrad 0x6a09e667U, 0xbb67ae85U, 0x3c6ef372U, 0xa54ff53aU, 74 1.1 riastrad 0x510e527fU, 0x9b05688cU, 0x1f83d9abU, 0x5be0cd19U, 75 1.1 riastrad }; 76 1.1 riastrad 77 1.1 riastrad static const uint8_t blake2s_sigma[10][16] = { 78 1.1 riastrad { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, 79 1.1 riastrad { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }, 80 1.1 riastrad { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 }, 81 1.1 riastrad { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 }, 82 1.1 riastrad { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 }, 83 1.1 riastrad { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 }, 84 1.1 riastrad { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 }, 85 1.1 riastrad { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 }, 86 1.1 riastrad { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 }, 87 1.1 riastrad { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 }, 88 1.1 riastrad }; 89 1.1 riastrad 90 1.1 riastrad static void 91 1.1 riastrad blake2s_compress(uint32_t h[8], uint64_t c, uint32_t last, 92 1.1 riastrad const uint8_t in[64]) 93 1.1 riastrad { 94 1.1 riastrad uint32_t v0,v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,v11,v12,v13,v14,v15; 95 1.1 riastrad uint32_t m[16]; 96 1.1 riastrad unsigned i; 97 1.1 riastrad 98 1.1 riastrad /* Load the variables: first 8 from state, next 8 from IV. */ 99 1.1 riastrad v0 = h[0]; 100 1.1 riastrad v1 = h[1]; 101 1.1 riastrad v2 = h[2]; 102 1.1 riastrad v3 = h[3]; 103 1.1 riastrad v4 = h[4]; 104 1.1 riastrad v5 = h[5]; 105 1.1 riastrad v6 = h[6]; 106 1.1 riastrad v7 = h[7]; 107 1.1 riastrad v8 = blake2s_iv[0]; 108 1.1 riastrad v9 = blake2s_iv[1]; 109 1.1 riastrad v10 = blake2s_iv[2]; 110 1.1 riastrad v11 = blake2s_iv[3]; 111 1.1 riastrad v12 = blake2s_iv[4]; 112 1.1 riastrad v13 = blake2s_iv[5]; 113 1.1 riastrad v14 = blake2s_iv[6]; 114 1.1 riastrad v15 = blake2s_iv[7]; 115 1.1 riastrad 116 1.1 riastrad /* Incorporate the block counter and whether this is last. */ 117 1.1 riastrad v12 ^= c & 0xffffffffU; 118 1.1 riastrad v13 ^= c >> 32; 119 1.1 riastrad v14 ^= last; 120 1.1 riastrad 121 1.1 riastrad /* Load the message block. */ 122 1.1 riastrad for (i = 0; i < 16; i++) 123 1.1 riastrad m[i] = le32dec(in + 4*i); 124 1.1 riastrad 125 1.1 riastrad /* Transform the variables. */ 126 1.1 riastrad for (i = 0; i < 10; i++) { 127 1.1 riastrad const uint8_t *sigma = blake2s_sigma[i]; 128 1.1 riastrad 129 1.1 riastrad BLAKE2S_G(v0, v4, v8, v12, m[sigma[ 0]], m[sigma[ 1]]); 130 1.1 riastrad BLAKE2S_G(v1, v5, v9, v13, m[sigma[ 2]], m[sigma[ 3]]); 131 1.1 riastrad BLAKE2S_G(v2, v6, v10, v14, m[sigma[ 4]], m[sigma[ 5]]); 132 1.1 riastrad BLAKE2S_G(v3, v7, v11, v15, m[sigma[ 6]], m[sigma[ 7]]); 133 1.1 riastrad BLAKE2S_G(v0, v5, v10, v15, m[sigma[ 8]], m[sigma[ 9]]); 134 1.1 riastrad BLAKE2S_G(v1, v6, v11, v12, m[sigma[10]], m[sigma[11]]); 135 1.1 riastrad BLAKE2S_G(v2, v7, v8, v13, m[sigma[12]], m[sigma[13]]); 136 1.1 riastrad BLAKE2S_G(v3, v4, v9, v14, m[sigma[14]], m[sigma[15]]); 137 1.1 riastrad } 138 1.1 riastrad 139 1.1 riastrad /* Update the state. */ 140 1.1 riastrad h[0] ^= v0 ^ v8; 141 1.1 riastrad h[1] ^= v1 ^ v9; 142 1.1 riastrad h[2] ^= v2 ^ v10; 143 1.1 riastrad h[3] ^= v3 ^ v11; 144 1.1 riastrad h[4] ^= v4 ^ v12; 145 1.1 riastrad h[5] ^= v5 ^ v13; 146 1.1 riastrad h[6] ^= v6 ^ v14; 147 1.1 riastrad h[7] ^= v7 ^ v15; 148 1.1 riastrad 149 1.1 riastrad (void)explicit_memset(m, 0, sizeof m); 150 1.1 riastrad } 151 1.1 riastrad 152 1.1 riastrad void 153 1.1 riastrad blake2s_init(struct blake2s *B, size_t dlen, const void *key, size_t keylen) 154 1.1 riastrad { 155 1.1 riastrad uint32_t param0; 156 1.1 riastrad unsigned i; 157 1.1 riastrad 158 1.1 riastrad assert(0 < dlen); 159 1.1 riastrad assert(dlen <= 32); 160 1.1 riastrad assert(keylen <= 32); 161 1.1 riastrad 162 1.1 riastrad /* Record the digest length. */ 163 1.1 riastrad B->dlen = dlen; 164 1.1 riastrad 165 1.1 riastrad /* Initialize the buffer. */ 166 1.1 riastrad B->nb = 0; 167 1.1 riastrad 168 1.1 riastrad /* Initialize the state. */ 169 1.1 riastrad B->c = 0; 170 1.1 riastrad for (i = 0; i < 8; i++) 171 1.1 riastrad B->h[i] = blake2s_iv[i]; 172 1.1 riastrad 173 1.1 riastrad /* 174 1.1 riastrad * Set the parameters. We support only variable digest and key 175 1.1 riastrad * lengths: no tree hashing, no salt, no personalization. 176 1.1 riastrad */ 177 1.1 riastrad param0 = 0; 178 1.1 riastrad param0 |= (uint32_t)dlen << 0; 179 1.1 riastrad param0 |= (uint32_t)keylen << 8; 180 1.1 riastrad param0 |= (uint32_t)1 << 16; /* tree fanout = 1 */ 181 1.1 riastrad param0 |= (uint32_t)1 << 24; /* tree depth = 1 */ 182 1.1 riastrad B->h[0] ^= param0; 183 1.1 riastrad 184 1.1 riastrad /* If there's a key, compress it as the first message block. */ 185 1.1 riastrad if (keylen) { 186 1.1 riastrad static const uint8_t zero_block[64]; 187 1.1 riastrad 188 1.1 riastrad blake2s_update(B, key, keylen); 189 1.1 riastrad blake2s_update(B, zero_block, 64 - keylen); 190 1.1 riastrad } 191 1.1 riastrad } 192 1.1 riastrad 193 1.1 riastrad void 194 1.1 riastrad blake2s_update(struct blake2s *B, const void *buf, size_t len) 195 1.1 riastrad { 196 1.1 riastrad const uint8_t *p = buf; 197 1.1 riastrad size_t n = len; 198 1.1 riastrad 199 1.1 riastrad /* Check the current state of the buffer. */ 200 1.1 riastrad if (n <= 64u - B->nb) { 201 1.1 riastrad /* Can at most exactly fill the buffer. */ 202 1.1 riastrad (void)memcpy(&B->b[B->nb], p, n); 203 1.1 riastrad B->nb += n; 204 1.1 riastrad return; 205 1.1 riastrad } else if (0 < B->nb) { 206 1.1 riastrad /* Can fill the buffer and go on. */ 207 1.1 riastrad (void)memcpy(&B->b[B->nb], p, 64 - B->nb); 208 1.1 riastrad B->c += 64; 209 1.1 riastrad blake2s_compress(B->h, B->c, 0, B->b); 210 1.1 riastrad p += 64 - B->nb; 211 1.1 riastrad n -= 64 - B->nb; 212 1.1 riastrad } 213 1.1 riastrad 214 1.1 riastrad /* At a block boundary. Compress straight from the input. */ 215 1.1 riastrad while (64 < n) { 216 1.1 riastrad B->c += 64; 217 1.1 riastrad blake2s_compress(B->h, B->c, 0, p); 218 1.1 riastrad p += 64; 219 1.1 riastrad n -= 64; 220 1.1 riastrad } 221 1.1 riastrad 222 1.1 riastrad /* 223 1.1 riastrad * Put whatever's left in the buffer. We may fill the buffer, 224 1.1 riastrad * but we can't compress in that case until we know whether we 225 1.1 riastrad * are compressing the last block or not. 226 1.1 riastrad */ 227 1.1 riastrad (void)memcpy(B->b, p, n); 228 1.1 riastrad B->nb = n; 229 1.1 riastrad } 230 1.1 riastrad 231 1.1 riastrad void 232 1.1 riastrad blake2s_final(struct blake2s *B, void *digest) 233 1.1 riastrad { 234 1.1 riastrad uint8_t *d = digest; 235 1.1 riastrad unsigned dlen = B->dlen; 236 1.1 riastrad unsigned i; 237 1.1 riastrad 238 1.1 riastrad /* Pad with zeros, and do the last compression. */ 239 1.1 riastrad B->c += B->nb; 240 1.1 riastrad for (i = B->nb; i < 64; i++) 241 1.1 riastrad B->b[i] = 0; 242 1.1 riastrad blake2s_compress(B->h, B->c, ~(uint32_t)0, B->b); 243 1.1 riastrad 244 1.1 riastrad /* Reveal the first dlen/4 words of the state. */ 245 1.1 riastrad for (i = 0; i < dlen/4; i++) 246 1.1 riastrad le32enc(d + 4*i, B->h[i]); 247 1.1 riastrad d += 4*i; 248 1.1 riastrad dlen -= 4*i; 249 1.1 riastrad 250 1.1 riastrad /* If the caller wants a partial word, reveal that too. */ 251 1.1 riastrad if (dlen) { 252 1.1 riastrad uint32_t hi = B->h[i]; 253 1.1 riastrad 254 1.1 riastrad do { 255 1.1 riastrad *d++ = hi; 256 1.1 riastrad hi >>= 8; 257 1.1 riastrad } while (--dlen); 258 1.1 riastrad } 259 1.1 riastrad 260 1.1 riastrad /* Erase the state. */ 261 1.1 riastrad (void)explicit_memset(B, 0, sizeof B); 262 1.1 riastrad } 263 1.1 riastrad 264 1.1 riastrad void 265 1.1 riastrad blake2s(void *digest, size_t dlen, const void *key, size_t keylen, 266 1.1 riastrad const void *in, size_t inlen) 267 1.1 riastrad { 268 1.1 riastrad struct blake2s ctx; 269 1.1 riastrad 270 1.1 riastrad blake2s_init(&ctx, dlen, key, keylen); 271 1.1 riastrad blake2s_update(&ctx, in, inlen); 272 1.1 riastrad blake2s_final(&ctx, digest); 273 1.1 riastrad } 274 1.1 riastrad 275 1.1 riastrad static void 276 1.1 riastrad blake2_selftest_prng(void *buf, size_t len, uint32_t seed) 277 1.1 riastrad { 278 1.1 riastrad uint8_t *p = buf; 279 1.1 riastrad size_t n = len; 280 1.1 riastrad uint32_t t, a, b; 281 1.1 riastrad 282 1.1 riastrad a = 0xdead4bad * seed; 283 1.1 riastrad b = 1; 284 1.1 riastrad 285 1.1 riastrad while (n--) { 286 1.1 riastrad t = a + b; 287 1.1 riastrad *p++ = t >> 24; 288 1.1 riastrad a = b; 289 1.1 riastrad b = t; 290 1.1 riastrad } 291 1.1 riastrad } 292 1.1 riastrad 293 1.1 riastrad int 294 1.1 riastrad blake2s_selftest(void) 295 1.1 riastrad { 296 1.1 riastrad const uint8_t d0[32] = { 297 1.1 riastrad 0x6a,0x41,0x1f,0x08,0xce,0x25,0xad,0xcd, 298 1.1 riastrad 0xfb,0x02,0xab,0xa6,0x41,0x45,0x1c,0xec, 299 1.1 riastrad 0x53,0xc5,0x98,0xb2,0x4f,0x4f,0xc7,0x87, 300 1.1 riastrad 0xfb,0xdc,0x88,0x79,0x7f,0x4c,0x1d,0xfe, 301 1.1 riastrad }; 302 1.1 riastrad const unsigned dlen[4] = { 16, 20, 28, 32 }; 303 1.1 riastrad const unsigned mlen[6] = { 0, 3, 64, 65, 255, 1024 }; 304 1.1 riastrad uint8_t m[1024], d[32], k[32]; 305 1.1 riastrad struct blake2s ctx; 306 1.1 riastrad unsigned di, mi, i; 307 1.1 riastrad 308 1.1 riastrad blake2s_init(&ctx, 32, NULL, 0); 309 1.1 riastrad for (di = 0; di < 4; di++) { 310 1.1 riastrad for (mi = 0; mi < 6; mi++) { 311 1.1 riastrad blake2_selftest_prng(m, mlen[mi], mlen[mi]); 312 1.1 riastrad blake2s(d, dlen[di], NULL, 0, m, mlen[mi]); 313 1.1 riastrad blake2s_update(&ctx, d, dlen[di]); 314 1.1 riastrad 315 1.1 riastrad blake2_selftest_prng(k, dlen[di], dlen[di]); 316 1.1 riastrad blake2s(d, dlen[di], k, dlen[di], m, mlen[mi]); 317 1.1 riastrad blake2s_update(&ctx, d, dlen[di]); 318 1.1 riastrad } 319 1.1 riastrad } 320 1.1 riastrad blake2s_final(&ctx, d); 321 1.1 riastrad for (i = 0; i < 32; i++) { 322 1.1 riastrad if (d[i] != d0[i]) 323 1.1 riastrad return -1; 324 1.1 riastrad } 325 1.1 riastrad 326 1.1 riastrad return 0; 327 1.1 riastrad } 328 1.1 riastrad 329 1.1 riastrad #ifdef _KERNEL 330 1.1 riastrad 331 1.1 riastrad MODULE(MODULE_CLASS_MISC, blake2s, NULL); 332 1.1 riastrad 333 1.1 riastrad static int 334 1.1 riastrad blake2s_modcmd(modcmd_t cmd, void *opaque) 335 1.1 riastrad { 336 1.1 riastrad 337 1.1 riastrad switch (cmd) { 338 1.1 riastrad case MODULE_CMD_INIT: 339 1.1 riastrad if (blake2s_selftest()) 340 1.1 riastrad panic("blake2s: self-test failed"); 341 1.2 jmcneill aprint_debug("blake2s: self-test passed\n"); 342 1.1 riastrad return 0; 343 1.1 riastrad case MODULE_CMD_FINI: 344 1.1 riastrad return 0; 345 1.1 riastrad default: 346 1.1 riastrad return ENOTTY; 347 1.1 riastrad } 348 1.1 riastrad } 349 1.1 riastrad 350 1.1 riastrad #endif 351