"Fossies" - the Fresh Open Source Software Archive

Member "cryptsetup-2.4.3/lib/crypto_backend/argon2/blake2/blake2b.c" (13 Jan 2022, 12560 Bytes) of package /linux/misc/cryptsetup-2.4.3.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "blake2b.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * Argon2 reference source code package - reference C implementations
    3  *
    4  * Copyright 2015
    5  * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
    6  *
    7  * You may use this work under the terms of a Creative Commons CC0 1.0
    8  * License/Waiver or the Apache Public License 2.0, at your option. The terms of
    9  * these licenses can be found at:
   10  *
   11  * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
   12  * - Apache 2.0        : https://www.apache.org/licenses/LICENSE-2.0
   13  *
   14  * You should have received a copy of both of these licenses along with this
   15  * software. If not, they may be obtained at the above URLs.
   16  */
   17 
   18 #include <stdint.h>
   19 #include <string.h>
   20 #include <stdio.h>
   21 
   22 #include "blake2.h"
   23 #include "blake2-impl.h"
   24 
   25 void clear_internal_memory(void *v, size_t n);
   26 
   27 static const uint64_t blake2b_IV[8] = {
   28     UINT64_C(0x6a09e667f3bcc908), UINT64_C(0xbb67ae8584caa73b),
   29     UINT64_C(0x3c6ef372fe94f82b), UINT64_C(0xa54ff53a5f1d36f1),
   30     UINT64_C(0x510e527fade682d1), UINT64_C(0x9b05688c2b3e6c1f),
   31     UINT64_C(0x1f83d9abfb41bd6b), UINT64_C(0x5be0cd19137e2179)};
   32 
   33 static const unsigned int blake2b_sigma[12][16] = {
   34     {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
   35     {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3},
   36     {11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4},
   37     {7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8},
   38     {9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13},
   39     {2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9},
   40     {12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11},
   41     {13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10},
   42     {6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5},
   43     {10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0},
   44     {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
   45     {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3},
   46 };
   47 
   48 static BLAKE2_INLINE void blake2b_set_lastnode(blake2b_state *S) {
   49     S->f[1] = (uint64_t)-1;
   50 }
   51 
   52 static BLAKE2_INLINE void blake2b_set_lastblock(blake2b_state *S) {
   53     if (S->last_node) {
   54         blake2b_set_lastnode(S);
   55     }
   56     S->f[0] = (uint64_t)-1;
   57 }
   58 
   59 static BLAKE2_INLINE void blake2b_increment_counter(blake2b_state *S,
   60                                                     uint64_t inc) {
   61     S->t[0] += inc;
   62     S->t[1] += (S->t[0] < inc);
   63 }
   64 
   65 static BLAKE2_INLINE void blake2b_invalidate_state(blake2b_state *S) {
   66     clear_internal_memory(S, sizeof(*S));      /* wipe */
   67     blake2b_set_lastblock(S); /* invalidate for further use */
   68 }
   69 
   70 static BLAKE2_INLINE void blake2b_init0(blake2b_state *S) {
   71     memset(S, 0, sizeof(*S));
   72     memcpy(S->h, blake2b_IV, sizeof(S->h));
   73 }
   74 
   75 int blake2b_init_param(blake2b_state *S, const blake2b_param *P) {
   76     const unsigned char *p = (const unsigned char *)P;
   77     unsigned int i;
   78 
   79     if (NULL == P || NULL == S) {
   80         return -1;
   81     }
   82 
   83     blake2b_init0(S);
   84     /* IV XOR Parameter Block */
   85     for (i = 0; i < 8; ++i) {
   86         S->h[i] ^= load64(&p[i * sizeof(S->h[i])]);
   87     }
   88     S->outlen = P->digest_length;
   89     return 0;
   90 }
   91 
   92 /* Sequential blake2b initialization */
   93 int blake2b_init(blake2b_state *S, size_t outlen) {
   94     blake2b_param P;
   95 
   96     if (S == NULL) {
   97         return -1;
   98     }
   99 
  100     if ((outlen == 0) || (outlen > BLAKE2B_OUTBYTES)) {
  101         blake2b_invalidate_state(S);
  102         return -1;
  103     }
  104 
  105     /* Setup Parameter Block for unkeyed BLAKE2 */
  106     P.digest_length = (uint8_t)outlen;
  107     P.key_length = 0;
  108     P.fanout = 1;
  109     P.depth = 1;
  110     P.leaf_length = 0;
  111     P.node_offset = 0;
  112     P.node_depth = 0;
  113     P.inner_length = 0;
  114     memset(P.reserved, 0, sizeof(P.reserved));
  115     memset(P.salt, 0, sizeof(P.salt));
  116     memset(P.personal, 0, sizeof(P.personal));
  117 
  118     return blake2b_init_param(S, &P);
  119 }
  120 
  121 int blake2b_init_key(blake2b_state *S, size_t outlen, const void *key,
  122                      size_t keylen) {
  123     blake2b_param P;
  124 
  125     if (S == NULL) {
  126         return -1;
  127     }
  128 
  129     if ((outlen == 0) || (outlen > BLAKE2B_OUTBYTES)) {
  130         blake2b_invalidate_state(S);
  131         return -1;
  132     }
  133 
  134     if ((key == 0) || (keylen == 0) || (keylen > BLAKE2B_KEYBYTES)) {
  135         blake2b_invalidate_state(S);
  136         return -1;
  137     }
  138 
  139     /* Setup Parameter Block for keyed BLAKE2 */
  140     P.digest_length = (uint8_t)outlen;
  141     P.key_length = (uint8_t)keylen;
  142     P.fanout = 1;
  143     P.depth = 1;
  144     P.leaf_length = 0;
  145     P.node_offset = 0;
  146     P.node_depth = 0;
  147     P.inner_length = 0;
  148     memset(P.reserved, 0, sizeof(P.reserved));
  149     memset(P.salt, 0, sizeof(P.salt));
  150     memset(P.personal, 0, sizeof(P.personal));
  151 
  152     if (blake2b_init_param(S, &P) < 0) {
  153         blake2b_invalidate_state(S);
  154         return -1;
  155     }
  156 
  157     {
  158         uint8_t block[BLAKE2B_BLOCKBYTES];
  159         memset(block, 0, BLAKE2B_BLOCKBYTES);
  160         memcpy(block, key, keylen);
  161         blake2b_update(S, block, BLAKE2B_BLOCKBYTES);
  162         /* Burn the key from stack */
  163         clear_internal_memory(block, BLAKE2B_BLOCKBYTES);
  164     }
  165     return 0;
  166 }
  167 
  168 static void blake2b_compress(blake2b_state *S, const uint8_t *block) {
  169     uint64_t m[16];
  170     uint64_t v[16];
  171     unsigned int i, r;
  172 
  173     for (i = 0; i < 16; ++i) {
  174         m[i] = load64(block + i * sizeof(m[i]));
  175     }
  176 
  177     for (i = 0; i < 8; ++i) {
  178         v[i] = S->h[i];
  179     }
  180 
  181     v[8] = blake2b_IV[0];
  182     v[9] = blake2b_IV[1];
  183     v[10] = blake2b_IV[2];
  184     v[11] = blake2b_IV[3];
  185     v[12] = blake2b_IV[4] ^ S->t[0];
  186     v[13] = blake2b_IV[5] ^ S->t[1];
  187     v[14] = blake2b_IV[6] ^ S->f[0];
  188     v[15] = blake2b_IV[7] ^ S->f[1];
  189 
  190 #define G(r, i, a, b, c, d)                                                    \
  191     do {                                                                       \
  192         a = a + b + m[blake2b_sigma[r][2 * i + 0]];                            \
  193         d = rotr64(d ^ a, 32);                                                 \
  194         c = c + d;                                                             \
  195         b = rotr64(b ^ c, 24);                                                 \
  196         a = a + b + m[blake2b_sigma[r][2 * i + 1]];                            \
  197         d = rotr64(d ^ a, 16);                                                 \
  198         c = c + d;                                                             \
  199         b = rotr64(b ^ c, 63);                                                 \
  200     } while ((void)0, 0)
  201 
  202 #define ROUND(r)                                                               \
  203     do {                                                                       \
  204         G(r, 0, v[0], v[4], v[8], v[12]);                                      \
  205         G(r, 1, v[1], v[5], v[9], v[13]);                                      \
  206         G(r, 2, v[2], v[6], v[10], v[14]);                                     \
  207         G(r, 3, v[3], v[7], v[11], v[15]);                                     \
  208         G(r, 4, v[0], v[5], v[10], v[15]);                                     \
  209         G(r, 5, v[1], v[6], v[11], v[12]);                                     \
  210         G(r, 6, v[2], v[7], v[8], v[13]);                                      \
  211         G(r, 7, v[3], v[4], v[9], v[14]);                                      \
  212     } while ((void)0, 0)
  213 
  214     for (r = 0; r < 12; ++r) {
  215         ROUND(r);
  216     }
  217 
  218     for (i = 0; i < 8; ++i) {
  219         S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
  220     }
  221 
  222 #undef G
  223 #undef ROUND
  224 }
  225 
  226 int blake2b_update(blake2b_state *S, const void *in, size_t inlen) {
  227     const uint8_t *pin = (const uint8_t *)in;
  228 
  229     if (inlen == 0) {
  230         return 0;
  231     }
  232 
  233     /* Sanity check */
  234     if (S == NULL || in == NULL) {
  235         return -1;
  236     }
  237 
  238     /* Is this a reused state? */
  239     if (S->f[0] != 0) {
  240         return -1;
  241     }
  242 
  243     if (S->buflen + inlen > BLAKE2B_BLOCKBYTES) {
  244         /* Complete current block */
  245         size_t left = S->buflen;
  246         size_t fill = BLAKE2B_BLOCKBYTES - left;
  247         memcpy(&S->buf[left], pin, fill);
  248         blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES);
  249         blake2b_compress(S, S->buf);
  250         S->buflen = 0;
  251         inlen -= fill;
  252         pin += fill;
  253         /* Avoid buffer copies when possible */
  254         while (inlen > BLAKE2B_BLOCKBYTES) {
  255             blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES);
  256             blake2b_compress(S, pin);
  257             inlen -= BLAKE2B_BLOCKBYTES;
  258             pin += BLAKE2B_BLOCKBYTES;
  259         }
  260     }
  261     memcpy(&S->buf[S->buflen], pin, inlen);
  262     S->buflen += (unsigned int)inlen;
  263     return 0;
  264 }
  265 
  266 int blake2b_final(blake2b_state *S, void *out, size_t outlen) {
  267     uint8_t buffer[BLAKE2B_OUTBYTES] = {0};
  268     unsigned int i;
  269 
  270     /* Sanity checks */
  271     if (S == NULL || out == NULL || outlen < S->outlen) {
  272         return -1;
  273     }
  274 
  275     /* Is this a reused state? */
  276     if (S->f[0] != 0) {
  277         return -1;
  278     }
  279 
  280     blake2b_increment_counter(S, S->buflen);
  281     blake2b_set_lastblock(S);
  282     memset(&S->buf[S->buflen], 0, BLAKE2B_BLOCKBYTES - S->buflen); /* Padding */
  283     blake2b_compress(S, S->buf);
  284 
  285     for (i = 0; i < 8; ++i) { /* Output full hash to temp buffer */
  286         store64(buffer + sizeof(S->h[i]) * i, S->h[i]);
  287     }
  288 
  289     memcpy(out, buffer, S->outlen);
  290     clear_internal_memory(buffer, sizeof(buffer));
  291     clear_internal_memory(S->buf, sizeof(S->buf));
  292     clear_internal_memory(S->h, sizeof(S->h));
  293     return 0;
  294 }
  295 
  296 int blake2b(void *out, size_t outlen, const void *in, size_t inlen,
  297             const void *key, size_t keylen) {
  298     blake2b_state S;
  299     int ret = -1;
  300 
  301     /* Verify parameters */
  302     if (NULL == in && inlen > 0) {
  303         goto fail;
  304     }
  305 
  306     if (NULL == out || outlen == 0 || outlen > BLAKE2B_OUTBYTES) {
  307         goto fail;
  308     }
  309 
  310     if ((NULL == key && keylen > 0) || keylen > BLAKE2B_KEYBYTES) {
  311         goto fail;
  312     }
  313 
  314     if (keylen > 0) {
  315         if (blake2b_init_key(&S, outlen, key, keylen) < 0) {
  316             goto fail;
  317         }
  318     } else {
  319         if (blake2b_init(&S, outlen) < 0) {
  320             goto fail;
  321         }
  322     }
  323 
  324     if (blake2b_update(&S, in, inlen) < 0) {
  325         goto fail;
  326     }
  327     ret = blake2b_final(&S, out, outlen);
  328 
  329 fail:
  330     clear_internal_memory(&S, sizeof(S));
  331     return ret;
  332 }
  333 
  334 /* Argon2 Team - Begin Code */
  335 int blake2b_long(void *pout, size_t outlen, const void *in, size_t inlen) {
  336     uint8_t *out = (uint8_t *)pout;
  337     blake2b_state blake_state;
  338     uint8_t outlen_bytes[sizeof(uint32_t)] = {0};
  339     int ret = -1;
  340 
  341     if (outlen > UINT32_MAX) {
  342         goto fail;
  343     }
  344 
  345     /* Ensure little-endian byte order! */
  346     store32(outlen_bytes, (uint32_t)outlen);
  347 
  348 #define TRY(statement)                                                         \
  349     do {                                                                       \
  350         ret = statement;                                                       \
  351         if (ret < 0) {                                                         \
  352             goto fail;                                                         \
  353         }                                                                      \
  354     } while ((void)0, 0)
  355 
  356     if (outlen <= BLAKE2B_OUTBYTES) {
  357         TRY(blake2b_init(&blake_state, outlen));
  358         TRY(blake2b_update(&blake_state, outlen_bytes, sizeof(outlen_bytes)));
  359         TRY(blake2b_update(&blake_state, in, inlen));
  360         TRY(blake2b_final(&blake_state, out, outlen));
  361     } else {
  362         uint32_t toproduce;
  363         uint8_t out_buffer[BLAKE2B_OUTBYTES];
  364         uint8_t in_buffer[BLAKE2B_OUTBYTES];
  365         TRY(blake2b_init(&blake_state, BLAKE2B_OUTBYTES));
  366         TRY(blake2b_update(&blake_state, outlen_bytes, sizeof(outlen_bytes)));
  367         TRY(blake2b_update(&blake_state, in, inlen));
  368         TRY(blake2b_final(&blake_state, out_buffer, BLAKE2B_OUTBYTES));
  369         memcpy(out, out_buffer, BLAKE2B_OUTBYTES / 2);
  370         out += BLAKE2B_OUTBYTES / 2;
  371         toproduce = (uint32_t)outlen - BLAKE2B_OUTBYTES / 2;
  372 
  373         while (toproduce > BLAKE2B_OUTBYTES) {
  374             memcpy(in_buffer, out_buffer, BLAKE2B_OUTBYTES);
  375             TRY(blake2b(out_buffer, BLAKE2B_OUTBYTES, in_buffer,
  376                         BLAKE2B_OUTBYTES, NULL, 0));
  377             memcpy(out, out_buffer, BLAKE2B_OUTBYTES / 2);
  378             out += BLAKE2B_OUTBYTES / 2;
  379             toproduce -= BLAKE2B_OUTBYTES / 2;
  380         }
  381 
  382         memcpy(in_buffer, out_buffer, BLAKE2B_OUTBYTES);
  383         TRY(blake2b(out_buffer, toproduce, in_buffer, BLAKE2B_OUTBYTES, NULL,
  384                     0));
  385         memcpy(out, out_buffer, toproduce);
  386     }
  387 fail:
  388     clear_internal_memory(&blake_state, sizeof(blake_state));
  389     return ret;
  390 #undef TRY
  391 }
  392 /* Argon2 Team - End Code */