argon2 0.0.2 → 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 +4 -4
- data/.rubocop.yml +66 -0
- data/.travis.yml +4 -0
- data/README.md +60 -5
- data/Rakefile +3 -0
- data/argon2.gemspec +10 -12
- data/ext/argon2_wrap/Makefile +4 -4
- data/ext/argon2_wrap/argon_wrap.c +57 -5
- data/ext/argon2_wrap/test.c +84 -12
- data/ext/phc-winner-argon2/.gitignore +1 -0
- data/ext/phc-winner-argon2/Makefile +1 -1
- data/ext/phc-winner-argon2/README.md +31 -26
- data/ext/phc-winner-argon2/src/argon2.c +133 -188
- data/ext/phc-winner-argon2/src/argon2.h +76 -42
- data/ext/phc-winner-argon2/src/core.c +0 -1
- data/ext/phc-winner-argon2/src/core.h +2 -3
- data/ext/phc-winner-argon2/src/encoding.c +435 -0
- data/ext/phc-winner-argon2/src/encoding.h +7 -0
- data/ext/phc-winner-argon2/src/run.c +43 -58
- data/lib/argon2.rb +21 -2
- data/lib/argon2/constants.rb +3 -0
- data/lib/argon2/engine.rb +1 -1
- data/lib/argon2/errors.rb +35 -30
- data/lib/argon2/ffi_engine.rb +43 -21
- data/lib/argon2/version.rb +2 -2
- metadata +51 -7
| @@ -14,7 +14,7 @@ GENKAT = genkat | |
| 14 14 | 
             
            DIST = phc-winner-argon2
         | 
| 15 15 |  | 
| 16 16 | 
             
            CC = gcc
         | 
| 17 | 
            -
            SRC = src/argon2.c src/core.c src/blake2/blake2b.c src/thread.c
         | 
| 17 | 
            +
            SRC = src/argon2.c src/core.c src/blake2/blake2b.c src/thread.c src/encoding.c
         | 
| 18 18 | 
             
            SRC_RUN = src/run.c
         | 
| 19 19 | 
             
            SRC_BENCH = src/bench.c
         | 
| 20 20 | 
             
            SRC_GENKAT = src/genkat.c
         | 
| @@ -36,10 +36,9 @@ results. | |
| 36 36 | 
             
            on your system. To show usage instructions, run
         | 
| 37 37 | 
             
            `./argon2` without arguments as
         | 
| 38 38 | 
             
            ```
         | 
| 39 | 
            -
             | 
| 40 | 
            -
             | 
| 39 | 
            +
            Usage:  ./argon2 salt [-d] [-t iterations] [-m memory] [-p parallelism]
         | 
| 40 | 
            +
                    Password is read from stdin
         | 
| 41 41 | 
             
            Parameters:
         | 
| 42 | 
            -
                    pwd             The password to hash
         | 
| 43 42 | 
             
                    salt            The salt to use, at most 16 characters
         | 
| 44 43 | 
             
                    -d              Use Argon2d instead of Argon2i (which is the default)
         | 
| 45 44 | 
             
                    -t N            Sets the number of iterations to N (default = 3)
         | 
| @@ -49,13 +48,15 @@ Parameters: | |
| 49 48 | 
             
            For example, to hash "password" using "somesalt" as a salt and doing 2
         | 
| 50 49 | 
             
            iterations, consuming 64 MiB, and using four parallel threads:
         | 
| 51 50 | 
             
            ```
         | 
| 52 | 
            -
            $ ./argon2  | 
| 51 | 
            +
            $ echo -n "password" | ./argon2 somesalt -t 2 -m 16 -p 4
         | 
| 53 52 | 
             
            Type:           Argon2i
         | 
| 54 53 | 
             
            Iterations:     2
         | 
| 55 54 | 
             
            Memory:         65536 KiB
         | 
| 56 55 | 
             
            Parallelism:    4
         | 
| 57 56 | 
             
            Hash:           4162f32384d8f4790bd994cb73c83a4a29f076165ec18af3cfdcf10a8d1b9066
         | 
| 58 | 
            -
             | 
| 57 | 
            +
            Encoded:        $argon2i$m=65536,t=2,p=4$c29tZXNhbHQAAAAAAAAAAA$QWLzI4TY9HkL2ZTLc8g6SinwdhZewYrzz9zxCo0bkGY
         | 
| 58 | 
            +
            0.271 seconds
         | 
| 59 | 
            +
            Verification ok
         | 
| 59 60 | 
             
            ```
         | 
| 60 61 |  | 
| 61 62 | 
             
            ### Library
         | 
| @@ -83,48 +84,47 @@ below is named `test.c` and placed in the project's root directory. | |
| 83 84 | 
             
            #include <string.h>
         | 
| 84 85 | 
             
            #include <stdlib.h>
         | 
| 85 86 |  | 
| 86 | 
            -
            #define  | 
| 87 | 
            +
            #define HASHLEN 32
         | 
| 87 88 | 
             
            #define SALTLEN 16
         | 
| 88 89 | 
             
            #define PWD "password"
         | 
| 89 90 |  | 
| 90 91 | 
             
            int main(void)
         | 
| 91 92 | 
             
            {
         | 
| 92 | 
            -
                uint8_t  | 
| 93 | 
            -
                uint8_t  | 
| 93 | 
            +
                uint8_t hash1[HASHLEN];
         | 
| 94 | 
            +
                uint8_t hash2[HASHLEN];
         | 
| 94 95 |  | 
| 95 96 | 
             
                uint8_t salt[SALTLEN];
         | 
| 96 97 | 
             
                memset( salt, 0x00, SALTLEN );
         | 
| 97 98 |  | 
| 98 | 
            -
                uint8_t * | 
| 99 | 
            -
                uint32_t  | 
| 99 | 
            +
                uint8_t *pwd = (uint8_t *)strdup(PWD);
         | 
| 100 | 
            +
                uint32_t pwdlen = strlen((char *)pwd);
         | 
| 100 101 |  | 
| 101 102 | 
             
                uint32_t t_cost = 2;            // 1-pass computation
         | 
| 102 103 | 
             
                uint32_t m_cost = (1<<16);      // 64 mebibytes memory usage
         | 
| 104 | 
            +
                uint32_t parallelism = 1;       // number of threads and lanes
         | 
| 103 105 |  | 
| 104 106 | 
             
                // high-level API
         | 
| 105 | 
            -
                 | 
| 106 | 
            -
                free(in);
         | 
| 107 | 
            +
                argon2i_hash_raw(t_cost, m_cost, parallelism, pwd, pwdlen, salt, SALTLEN, hash1, HASHLEN);
         | 
| 107 108 |  | 
| 108 109 | 
             
                // low-level API
         | 
| 109 | 
            -
                uint32_t lanes =  | 
| 110 | 
            -
                uint32_t threads =  | 
| 111 | 
            -
                in = (uint8_t *)strdup(PWD);    // was erased by previous call
         | 
| 110 | 
            +
                uint32_t lanes = parallelism;
         | 
| 111 | 
            +
                uint32_t threads = parallelism;
         | 
| 112 112 | 
             
                argon2_context context = {
         | 
| 113 | 
            -
                     | 
| 114 | 
            -
                     | 
| 113 | 
            +
                    hash2, HASHLEN, 
         | 
| 114 | 
            +
                    pwd, pwdlen, 
         | 
| 115 115 | 
             
                    salt, SALTLEN,
         | 
| 116 116 | 
             
                    NULL, 0, /* secret data */
         | 
| 117 117 | 
             
                    NULL, 0, /* associated data */
         | 
| 118 | 
            -
                    t_cost, m_cost,  | 
| 118 | 
            +
                    t_cost, m_cost, parallelism, parallelism, 
         | 
| 119 119 | 
             
                    NULL, NULL, /* custom memory allocation / deallocation functions */
         | 
| 120 120 | 
             
                    ARGON2_DEFAULT_FLAGS /* by default the password is zeroed on exit */
         | 
| 121 121 | 
             
                };
         | 
| 122 122 | 
             
                argon2i( &context );
         | 
| 123 | 
            -
                free( | 
| 123 | 
            +
                free(pwd);
         | 
| 124 124 |  | 
| 125 | 
            -
                for( int i=0; i< | 
| 126 | 
            -
                if (memcmp( | 
| 127 | 
            -
                    for( int i=0; i< | 
| 125 | 
            +
                for( int i=0; i<HASHLEN; ++i ) printf( "%02x", hash1[i] ); printf( "\n" );
         | 
| 126 | 
            +
                if (memcmp(hash1, hash2, HASHLEN)) {
         | 
| 127 | 
            +
                    for( int i=0; i<HASHLEN; ++i ) printf( "%02x", hash2[i] ); printf( "\n" );
         | 
| 128 128 | 
             
                    printf("fail\n");
         | 
| 129 129 | 
             
                }
         | 
| 130 130 | 
             
                else printf("ok\n");
         | 
| @@ -133,17 +133,22 @@ int main(void) | |
| 133 133 | 
             
            }
         | 
| 134 134 | 
             
            ```
         | 
| 135 135 |  | 
| 136 | 
            -
            To use Argon2d instead of Argon2i call ` | 
| 137 | 
            -
            ` | 
| 136 | 
            +
            To use Argon2d instead of Argon2i call `argon2d_hash` instead of
         | 
| 137 | 
            +
            `argon2i_hash` using the high-level API, and `argon2d` instead of
         | 
| 138 138 | 
             
            `argon2i` using the low-level API.
         | 
| 139 139 |  | 
| 140 | 
            +
            To produce the crypt-like encoding rather than the raw hash, call
         | 
| 141 | 
            +
            `argon2i_hash_encoded` for Argon2i and `argon2d_hash_encoded` for Argon2d.
         | 
| 142 | 
            +
             | 
| 143 | 
            +
            See [`src/argon2.h`](src/argon2.h) for API detais.
         | 
| 144 | 
            +
             | 
| 140 145 | 
             
            *Note: in this example the salt is set to the all-`0x00` string for the
         | 
| 141 146 | 
             
            sake of simplicity, but in your application you should use a random salt.*
         | 
| 142 147 |  | 
| 143 148 |  | 
| 144 149 | 
             
            ### Benchmarks
         | 
| 145 150 |  | 
| 146 | 
            -
            `make bench` creates the  | 
| 151 | 
            +
            `make bench` creates the executable `bench`, which measures the execution
         | 
| 147 152 | 
             
            time of various Argon2 instances:
         | 
| 148 153 |  | 
| 149 154 | 
             
            ```
         | 
| @@ -182,7 +187,7 @@ repository is copyright (c) 2015 Daniel Dinu, Dmitry Khovratovich (main | |
| 182 187 | 
             
            authors), Jean-Philippe Aumasson and Samuel Neves, and under
         | 
| 183 188 | 
             
            [CC0 license](https://creativecommons.org/about/cc0).
         | 
| 184 189 |  | 
| 185 | 
            -
            The string encoding routines in [`src/ | 
| 190 | 
            +
            The string encoding routines in [`src/encoding.c`](src/encoding.c) are
         | 
| 186 191 | 
             
            copyright (c) 2015 Thomas Pornin, and under [CC0
         | 
| 187 192 | 
             
            license](https://creativecommons.org/about/cc0).
         | 
| 188 193 |  | 
| @@ -13,10 +13,12 @@ | |
| 13 13 |  | 
| 14 14 | 
             
            #include <stdint.h>
         | 
| 15 15 | 
             
            #include <string.h>
         | 
| 16 | 
            +
            #include <stdlib.h>
         | 
| 16 17 | 
             
            #include <stdio.h>
         | 
| 17 18 | 
             
            #include <limits.h>
         | 
| 18 19 |  | 
| 19 20 | 
             
            #include "argon2.h"
         | 
| 21 | 
            +
            #include "encoding.h"
         | 
| 20 22 | 
             
            #include "core.h"
         | 
| 21 23 |  | 
| 22 24 | 
             
            /* Error messages */
         | 
| @@ -96,22 +98,30 @@ static const char *Argon2_ErrorMessage[] = { | |
| 96 98 | 
             
                /*},
         | 
| 97 99 | 
             
            {ARGON2_THREADS_TOO_MANY, */ "Too many threads",
         | 
| 98 100 | 
             
                /*},
         | 
| 99 | 
            -
            {ARGON2_MISSING_ARGS, */ "Missing arguments", | 
| 101 | 
            +
            {ARGON2_MISSING_ARGS, */ "Missing arguments",
         | 
| 102 | 
            +
                /*},
         | 
| 103 | 
            +
            {ARGON2_ENCODING_FAIL, */ "Encoding failed",
         | 
| 104 | 
            +
                /*},
         | 
| 105 | 
            +
            {ARGON2_DECODING_FAIL, */ "Decoding failed", /*},*/
         | 
| 100 106 | 
             
            };
         | 
| 101 107 |  | 
| 102 | 
            -
            int  | 
| 103 | 
            -
             | 
| 104 | 
            -
             | 
| 108 | 
            +
            int argon2_hash(const uint32_t t_cost, const uint32_t m_cost,
         | 
| 109 | 
            +
                            const uint32_t parallelism, const void *pwd,
         | 
| 110 | 
            +
                            const size_t pwdlen, const void *salt, const size_t saltlen,
         | 
| 111 | 
            +
                            void *hash, const size_t hashlen, char *encoded,
         | 
| 112 | 
            +
                            const size_t encodedlen, argon2_type type) {
         | 
| 105 113 |  | 
| 106 114 | 
             
                argon2_context context;
         | 
| 115 | 
            +
                int result;
         | 
| 116 | 
            +
                uint8_t *out;
         | 
| 107 117 |  | 
| 108 118 | 
             
                /* Detect and reject overflowing sizes */
         | 
| 109 119 | 
             
                /* TODO: This should probably be fixed in the function signature */
         | 
| 110 | 
            -
                if ( | 
| 120 | 
            +
                if (pwdlen > UINT32_MAX) {
         | 
| 111 121 | 
             
                    return ARGON2_PWD_TOO_LONG;
         | 
| 112 122 | 
             
                }
         | 
| 113 123 |  | 
| 114 | 
            -
                if ( | 
| 124 | 
            +
                if (hashlen > UINT32_MAX) {
         | 
| 115 125 | 
             
                    return ARGON2_OUTPUT_TOO_LONG;
         | 
| 116 126 | 
             
                }
         | 
| 117 127 |  | 
| @@ -119,10 +129,12 @@ int hash_argon2i(void *out, size_t outlen, const void *in, size_t inlen, | |
| 119 129 | 
             
                    return ARGON2_SALT_TOO_LONG;
         | 
| 120 130 | 
             
                }
         | 
| 121 131 |  | 
| 132 | 
            +
                out = malloc(hashlen);
         | 
| 133 | 
            +
             | 
| 122 134 | 
             
                context.out = (uint8_t *)out;
         | 
| 123 | 
            -
                context.outlen = (uint32_t) | 
| 124 | 
            -
                context.pwd = (uint8_t *) | 
| 125 | 
            -
                context.pwdlen = (uint32_t) | 
| 135 | 
            +
                context.outlen = (uint32_t)hashlen;
         | 
| 136 | 
            +
                context.pwd = (uint8_t *)pwd;
         | 
| 137 | 
            +
                context.pwdlen = (uint32_t)pwdlen;
         | 
| 126 138 | 
             
                context.salt = (uint8_t *)salt;
         | 
| 127 139 | 
             
                context.saltlen = (uint32_t)saltlen;
         | 
| 128 140 | 
             
                context.secret = NULL;
         | 
| @@ -131,53 +143,131 @@ int hash_argon2i(void *out, size_t outlen, const void *in, size_t inlen, | |
| 131 143 | 
             
                context.adlen = 0;
         | 
| 132 144 | 
             
                context.t_cost = t_cost;
         | 
| 133 145 | 
             
                context.m_cost = m_cost;
         | 
| 134 | 
            -
                context.lanes =  | 
| 135 | 
            -
                context.threads =  | 
| 146 | 
            +
                context.lanes = parallelism;
         | 
| 147 | 
            +
                context.threads = parallelism;
         | 
| 136 148 | 
             
                context.allocate_cbk = NULL;
         | 
| 137 149 | 
             
                context.free_cbk = NULL;
         | 
| 138 150 | 
             
                context.flags = ARGON2_DEFAULT_FLAGS;
         | 
| 139 151 |  | 
| 140 | 
            -
                 | 
| 141 | 
            -
            }
         | 
| 152 | 
            +
                result = argon2_core(&context, type);
         | 
| 142 153 |  | 
| 143 | 
            -
             | 
| 144 | 
            -
             | 
| 145 | 
            -
             | 
| 146 | 
            -
             | 
| 154 | 
            +
                if (result != ARGON2_OK) {
         | 
| 155 | 
            +
                    memset(out, 0x00, hashlen);
         | 
| 156 | 
            +
                    free(out);
         | 
| 157 | 
            +
                    return result;
         | 
| 158 | 
            +
                }
         | 
| 147 159 |  | 
| 148 | 
            -
                /*  | 
| 149 | 
            -
                 | 
| 150 | 
            -
             | 
| 151 | 
            -
                    return ARGON2_PWD_TOO_LONG;
         | 
| 160 | 
            +
                /* if raw hash requested, write it */
         | 
| 161 | 
            +
                if (hash) {
         | 
| 162 | 
            +
                    memcpy(hash, out, hashlen);
         | 
| 152 163 | 
             
                }
         | 
| 153 164 |  | 
| 154 | 
            -
                if  | 
| 155 | 
            -
             | 
| 165 | 
            +
                /* if encoding requested, write it */
         | 
| 166 | 
            +
                if (encoded && encodedlen) {
         | 
| 167 | 
            +
                    if (!encode_string(encoded, encodedlen, &context, type)) {
         | 
| 168 | 
            +
                        memset(out, 0x00, hashlen);
         | 
| 169 | 
            +
                        memset(encoded, 0x00, encodedlen);
         | 
| 170 | 
            +
                        free(out);
         | 
| 171 | 
            +
                        return ARGON2_ENCODING_FAIL;
         | 
| 172 | 
            +
                    }
         | 
| 156 173 | 
             
                }
         | 
| 157 174 |  | 
| 158 | 
            -
                 | 
| 159 | 
            -
             | 
| 175 | 
            +
                free(out);
         | 
| 176 | 
            +
             | 
| 177 | 
            +
                return ARGON2_OK;
         | 
| 178 | 
            +
            }
         | 
| 179 | 
            +
             | 
| 180 | 
            +
            int argon2i_hash_encoded(const uint32_t t_cost, const uint32_t m_cost,
         | 
| 181 | 
            +
                                     const uint32_t parallelism, const void *pwd,
         | 
| 182 | 
            +
                                     const size_t pwdlen, const void *salt,
         | 
| 183 | 
            +
                                     const size_t saltlen, const size_t hashlen,
         | 
| 184 | 
            +
                                     char *encoded, const size_t encodedlen) {
         | 
| 185 | 
            +
             | 
| 186 | 
            +
                return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
         | 
| 187 | 
            +
                                   NULL, hashlen, encoded, encodedlen, Argon2_i);
         | 
| 188 | 
            +
            }
         | 
| 189 | 
            +
             | 
| 190 | 
            +
            int argon2i_hash_raw(const uint32_t t_cost, const uint32_t m_cost,
         | 
| 191 | 
            +
                                 const uint32_t parallelism, const void *pwd,
         | 
| 192 | 
            +
                                 const size_t pwdlen, const void *salt,
         | 
| 193 | 
            +
                                 const size_t saltlen, void *hash, const size_t hashlen) {
         | 
| 194 | 
            +
             | 
| 195 | 
            +
                return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
         | 
| 196 | 
            +
                                   hash, hashlen, NULL, 0, Argon2_i);
         | 
| 197 | 
            +
            }
         | 
| 198 | 
            +
             | 
| 199 | 
            +
            int argon2d_hash_encoded(const uint32_t t_cost, const uint32_t m_cost,
         | 
| 200 | 
            +
                                     const uint32_t parallelism, const void *pwd,
         | 
| 201 | 
            +
                                     const size_t pwdlen, const void *salt,
         | 
| 202 | 
            +
                                     const size_t saltlen, const size_t hashlen,
         | 
| 203 | 
            +
                                     char *encoded, const size_t encodedlen) {
         | 
| 204 | 
            +
             | 
| 205 | 
            +
                return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
         | 
| 206 | 
            +
                                   NULL, hashlen, encoded, encodedlen, Argon2_d);
         | 
| 207 | 
            +
            }
         | 
| 208 | 
            +
             | 
| 209 | 
            +
            int argon2d_hash_raw(const uint32_t t_cost, const uint32_t m_cost,
         | 
| 210 | 
            +
                                 const uint32_t parallelism, const void *pwd,
         | 
| 211 | 
            +
                                 const size_t pwdlen, const void *salt,
         | 
| 212 | 
            +
                                 const size_t saltlen, void *hash, const size_t hashlen) {
         | 
| 213 | 
            +
             | 
| 214 | 
            +
                return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
         | 
| 215 | 
            +
                                   hash, hashlen, NULL, 0, Argon2_d);
         | 
| 216 | 
            +
            }
         | 
| 217 | 
            +
             | 
| 218 | 
            +
            int argon2_compare(const uint8_t *b1, const uint8_t *b2, size_t len) {
         | 
| 219 | 
            +
                size_t i;
         | 
| 220 | 
            +
                uint8_t d = 0U;
         | 
| 221 | 
            +
             | 
| 222 | 
            +
                for (i = 0U; i < len; i++) {
         | 
| 223 | 
            +
                    d |= b1[i] ^ b2[i];
         | 
| 160 224 | 
             
                }
         | 
| 225 | 
            +
                return (int)((1 & ((d - 1) >> 8)) - 1);
         | 
| 226 | 
            +
            }
         | 
| 161 227 |  | 
| 162 | 
            -
             | 
| 163 | 
            -
             | 
| 164 | 
            -
             | 
| 165 | 
            -
                 | 
| 166 | 
            -
                 | 
| 167 | 
            -
                context.saltlen = (uint32_t)saltlen;
         | 
| 168 | 
            -
                context.secret = NULL;
         | 
| 169 | 
            -
                context.secretlen = 0;
         | 
| 170 | 
            -
                context.ad = NULL;
         | 
| 171 | 
            -
                context.adlen = 0;
         | 
| 172 | 
            -
                context.t_cost = t_cost;
         | 
| 173 | 
            -
                context.m_cost = m_cost;
         | 
| 174 | 
            -
                context.lanes = 1;
         | 
| 175 | 
            -
                context.threads = 1;
         | 
| 176 | 
            -
                context.allocate_cbk = NULL;
         | 
| 177 | 
            -
                context.free_cbk = NULL;
         | 
| 178 | 
            -
                context.flags = ARGON2_DEFAULT_FLAGS;
         | 
| 228 | 
            +
            int argon2_verify(const char *encoded, const void *pwd, const size_t pwdlen,
         | 
| 229 | 
            +
                              argon2_type type) {
         | 
| 230 | 
            +
             | 
| 231 | 
            +
                argon2_context ctx;
         | 
| 232 | 
            +
                uint8_t *out;
         | 
| 179 233 |  | 
| 180 | 
            -
                 | 
| 234 | 
            +
                /* max values, to be updated in decode_string */
         | 
| 235 | 
            +
                ctx.adlen = 512;
         | 
| 236 | 
            +
                ctx.saltlen = 512;
         | 
| 237 | 
            +
                ctx.outlen = 512;
         | 
| 238 | 
            +
             | 
| 239 | 
            +
                ctx.ad = malloc(ctx.adlen);
         | 
| 240 | 
            +
                ctx.salt = malloc(ctx.saltlen);
         | 
| 241 | 
            +
                ctx.out = malloc(ctx.outlen);
         | 
| 242 | 
            +
                out = malloc(ctx.outlen);
         | 
| 243 | 
            +
             | 
| 244 | 
            +
                decode_string(&ctx, encoded, type);
         | 
| 245 | 
            +
             | 
| 246 | 
            +
                argon2_hash(ctx.t_cost, ctx.m_cost, ctx.threads, pwd, pwdlen, ctx.salt,
         | 
| 247 | 
            +
                            ctx.saltlen, out, ctx.outlen, NULL, 0, type);
         | 
| 248 | 
            +
             | 
| 249 | 
            +
                free(ctx.ad);
         | 
| 250 | 
            +
                free(ctx.salt);
         | 
| 251 | 
            +
             | 
| 252 | 
            +
                if (argon2_compare(out, ctx.out, ctx.outlen)) {
         | 
| 253 | 
            +
                    free(out);
         | 
| 254 | 
            +
                    free(ctx.out);
         | 
| 255 | 
            +
                    return ARGON2_DECODING_FAIL;
         | 
| 256 | 
            +
                }
         | 
| 257 | 
            +
                free(out);
         | 
| 258 | 
            +
                free(ctx.out);
         | 
| 259 | 
            +
             | 
| 260 | 
            +
                return ARGON2_OK;
         | 
| 261 | 
            +
            }
         | 
| 262 | 
            +
             | 
| 263 | 
            +
            int argon2i_verify(const char *encoded, const void *pwd, const size_t pwdlen) {
         | 
| 264 | 
            +
             | 
| 265 | 
            +
                return argon2_verify(encoded, pwd, pwdlen, Argon2_i);
         | 
| 266 | 
            +
            }
         | 
| 267 | 
            +
             | 
| 268 | 
            +
            int argon2d_verify(const char *encoded, const void *pwd, const size_t pwdlen) {
         | 
| 269 | 
            +
             | 
| 270 | 
            +
                return argon2_verify(encoded, pwd, pwdlen, Argon2_d);
         | 
| 181 271 | 
             
            }
         | 
| 182 272 |  | 
| 183 273 | 
             
            int argon2d(argon2_context *context) { return argon2_core(context, Argon2_d); }
         | 
| @@ -213,148 +303,3 @@ const char *error_message(int error_code) { | |
| 213 303 | 
             
                }
         | 
| 214 304 | 
             
                return "Unknown error code.";
         | 
| 215 305 | 
             
            }
         | 
| 216 | 
            -
             | 
| 217 | 
            -
            /* encoding/decoding helpers */
         | 
| 218 | 
            -
             | 
| 219 | 
            -
            /*
         | 
| 220 | 
            -
             * Some macros for constant-time comparisons. These work over values in
         | 
| 221 | 
            -
             * the 0..255 range. Returned value is 0x00 on "false", 0xFF on "true".
         | 
| 222 | 
            -
             */
         | 
| 223 | 
            -
            #define EQ(x, y) ((((0U - ((unsigned)(x) ^ (unsigned)(y))) >> 8) & 0xFF) ^ 0xFF)
         | 
| 224 | 
            -
            #define GT(x, y) ((((unsigned)(y) - (unsigned)(x)) >> 8) & 0xFF)
         | 
| 225 | 
            -
            #define GE(x, y) (GT(y, x) ^ 0xFF)
         | 
| 226 | 
            -
            #define LT(x, y) GT(y, x)
         | 
| 227 | 
            -
            #define LE(x, y) GE(y, x)
         | 
| 228 | 
            -
             | 
| 229 | 
            -
            /*
         | 
| 230 | 
            -
             * Convert value x (0..63) to corresponding Base64 character.
         | 
| 231 | 
            -
             */
         | 
| 232 | 
            -
            static int b64_byte_to_char(unsigned x) {
         | 
| 233 | 
            -
                return (LT(x, 26) & (x + 'A')) |
         | 
| 234 | 
            -
                       (GE(x, 26) & LT(x, 52) & (x + ('a' - 26))) |
         | 
| 235 | 
            -
                       (GE(x, 52) & LT(x, 62) & (x + ('0' - 52))) | (EQ(x, 62) & '+') |
         | 
| 236 | 
            -
                       (EQ(x, 63) & '/');
         | 
| 237 | 
            -
            }
         | 
| 238 | 
            -
             | 
| 239 | 
            -
            /*
         | 
| 240 | 
            -
             * Convert some bytes to Base64. 'dst_len' is the length (in characters)
         | 
| 241 | 
            -
             * of the output buffer 'dst'; if that buffer is not large enough to
         | 
| 242 | 
            -
             * receive the result (including the terminating 0), then (size_t)-1
         | 
| 243 | 
            -
             * is returned. Otherwise, the zero-terminated Base64 string is written
         | 
| 244 | 
            -
             * in the buffer, and the output length (counted WITHOUT the terminating
         | 
| 245 | 
            -
             * zero) is returned.
         | 
| 246 | 
            -
             */
         | 
| 247 | 
            -
            static size_t to_base64(char *dst, size_t dst_len, const void *src,
         | 
| 248 | 
            -
                                    size_t src_len) {
         | 
| 249 | 
            -
                size_t olen;
         | 
| 250 | 
            -
                const unsigned char *buf;
         | 
| 251 | 
            -
                unsigned acc, acc_len;
         | 
| 252 | 
            -
             | 
| 253 | 
            -
                olen = (src_len / 3) << 2;
         | 
| 254 | 
            -
                switch (src_len % 3) {
         | 
| 255 | 
            -
                case 2:
         | 
| 256 | 
            -
                    olen++;
         | 
| 257 | 
            -
                /* fall through */
         | 
| 258 | 
            -
                case 1:
         | 
| 259 | 
            -
                    olen += 2;
         | 
| 260 | 
            -
                    break;
         | 
| 261 | 
            -
                }
         | 
| 262 | 
            -
                if (dst_len <= olen) {
         | 
| 263 | 
            -
                    return (size_t)-1;
         | 
| 264 | 
            -
                }
         | 
| 265 | 
            -
                acc = 0;
         | 
| 266 | 
            -
                acc_len = 0;
         | 
| 267 | 
            -
                buf = (const unsigned char *)src;
         | 
| 268 | 
            -
                while (src_len-- > 0) {
         | 
| 269 | 
            -
                    acc = (acc << 8) + (*buf++);
         | 
| 270 | 
            -
                    acc_len += 8;
         | 
| 271 | 
            -
                    while (acc_len >= 6) {
         | 
| 272 | 
            -
                        acc_len -= 6;
         | 
| 273 | 
            -
                        *dst++ = b64_byte_to_char((acc >> acc_len) & 0x3F);
         | 
| 274 | 
            -
                    }
         | 
| 275 | 
            -
                }
         | 
| 276 | 
            -
                if (acc_len > 0) {
         | 
| 277 | 
            -
                    *dst++ = b64_byte_to_char((acc << (6 - acc_len)) & 0x3F);
         | 
| 278 | 
            -
                }
         | 
| 279 | 
            -
                *dst++ = 0;
         | 
| 280 | 
            -
                return olen;
         | 
| 281 | 
            -
            }
         | 
| 282 | 
            -
             | 
| 283 | 
            -
            /* ==================================================================== */
         | 
| 284 | 
            -
            /*
         | 
| 285 | 
            -
             * Code specific to Argon2i.
         | 
| 286 | 
            -
             *
         | 
| 287 | 
            -
             * The code below applies the following format:
         | 
| 288 | 
            -
             *
         | 
| 289 | 
            -
             *  $argon2i$m=<num>,t=<num>,p=<num>[,keyid=<bin>][,data=<bin>][$<bin>[$<bin>]]
         | 
| 290 | 
            -
             *
         | 
| 291 | 
            -
             * where <num> is a decimal integer (positive, fits in an 'unsigned long')
         | 
| 292 | 
            -
             * and <bin> is Base64-encoded data (no '=' padding characters, no newline
         | 
| 293 | 
            -
             * or whitespace). The "keyid" is a binary identifier for a key (up to 8
         | 
| 294 | 
            -
             * bytes); "data" is associated data (up to 32 bytes). When the 'keyid'
         | 
| 295 | 
            -
             * (resp. the 'data') is empty, then it is ommitted from the output.
         | 
| 296 | 
            -
             *
         | 
| 297 | 
            -
             * The last two binary chunks (encoded in Base64) are, in that order,
         | 
| 298 | 
            -
             * the salt and the output. Both are optional, but you cannot have an
         | 
| 299 | 
            -
             * output without a salt. The binary salt length is between 8 and 48 bytes.
         | 
| 300 | 
            -
             * The output length is always exactly 32 bytes.
         | 
| 301 | 
            -
             */
         | 
| 302 | 
            -
             | 
| 303 | 
            -
            int encode_string(char *dst, size_t dst_len, argon2_context *ctx) {
         | 
| 304 | 
            -
            #define SS(str)                                                                \
         | 
| 305 | 
            -
                do {                                                                       \
         | 
| 306 | 
            -
                    size_t pp_len = strlen(str);                                           \
         | 
| 307 | 
            -
                    if (pp_len >= dst_len) {                                               \
         | 
| 308 | 
            -
                        return 0;                                                          \
         | 
| 309 | 
            -
                    }                                                                      \
         | 
| 310 | 
            -
                    memcpy(dst, str, pp_len + 1);                                          \
         | 
| 311 | 
            -
                    dst += pp_len;                                                         \
         | 
| 312 | 
            -
                    dst_len -= pp_len;                                                     \
         | 
| 313 | 
            -
                } while (0)
         | 
| 314 | 
            -
             | 
| 315 | 
            -
            #define SX(x)                                                                  \
         | 
| 316 | 
            -
                do {                                                                       \
         | 
| 317 | 
            -
                    char tmp[30];                                                          \
         | 
| 318 | 
            -
                    sprintf(tmp, "%lu", (unsigned long)(x));                               \
         | 
| 319 | 
            -
                    SS(tmp);                                                               \
         | 
| 320 | 
            -
                } while (0);
         | 
| 321 | 
            -
             | 
| 322 | 
            -
            #define SB(buf, len)                                                           \
         | 
| 323 | 
            -
                do {                                                                       \
         | 
| 324 | 
            -
                    size_t sb_len = to_base64(dst, dst_len, buf, len);                     \
         | 
| 325 | 
            -
                    if (sb_len == (size_t)-1) {                                            \
         | 
| 326 | 
            -
                        return 0;                                                          \
         | 
| 327 | 
            -
                    }                                                                      \
         | 
| 328 | 
            -
                    dst += sb_len;                                                         \
         | 
| 329 | 
            -
                    dst_len -= sb_len;                                                     \
         | 
| 330 | 
            -
                } while (0);
         | 
| 331 | 
            -
             | 
| 332 | 
            -
                SS("$argon2i$m=");
         | 
| 333 | 
            -
                SX(ctx->m_cost);
         | 
| 334 | 
            -
                SS(",t=");
         | 
| 335 | 
            -
                SX(ctx->t_cost);
         | 
| 336 | 
            -
                SS(",p=");
         | 
| 337 | 
            -
                SX(ctx->lanes);
         | 
| 338 | 
            -
             | 
| 339 | 
            -
                if (ctx->adlen > 0) {
         | 
| 340 | 
            -
                    SS(",data=");
         | 
| 341 | 
            -
                    SB(ctx->ad, ctx->adlen);
         | 
| 342 | 
            -
                }
         | 
| 343 | 
            -
             | 
| 344 | 
            -
                if (ctx->saltlen == 0)
         | 
| 345 | 
            -
                    return 1;
         | 
| 346 | 
            -
             | 
| 347 | 
            -
                SS("$");
         | 
| 348 | 
            -
                SB(ctx->salt, ctx->saltlen);
         | 
| 349 | 
            -
             | 
| 350 | 
            -
                if (ctx->outlen == 0)
         | 
| 351 | 
            -
                    return 1;
         | 
| 352 | 
            -
             | 
| 353 | 
            -
                SS("$");
         | 
| 354 | 
            -
                SB(ctx->out, ctx->outlen);
         | 
| 355 | 
            -
                return 1;
         | 
| 356 | 
            -
             | 
| 357 | 
            -
            #undef SS
         | 
| 358 | 
            -
            #undef SX
         | 
| 359 | 
            -
            #undef SB
         | 
| 360 | 
            -
            }
         |