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