/* * Argon2 source code package * * Written by Daniel Dinu and Dmitry Khovratovich, 2015 * * This work is licensed under a Creative Commons CC0 1.0 License/Waiver. * * You should have received a copy of the CC0 Public Domain Dedication along * with this software. If not, see . */ #ifndef argon2_H #define argon2_H #include #include #include /* * Argon2 input parameter restrictions */ /* Minimum and maximum number of lanes (degree of parallelism) */ #define ARGON2_MIN_LANES UINT32_C(1) #define ARGON2_MAX_LANES UINT32_C(0xFFFFFF) /* Minimum and maximum number of threads */ #define ARGON2_MIN_THREADS UINT32_C(1) #define ARGON2_MAX_THREADS UINT32_C(0xFFFFFF) /* Number of synchronization points between lanes per pass */ #define ARGON2_SYNC_POINTS UINT32_C(4) /* Minimum and maximum digest size in bytes */ #define ARGON2_MIN_OUTLEN UINT32_C(16) #define ARGON2_MAX_OUTLEN UINT32_C(0xFFFFFFFF) /* Minimum and maximum number of memory blocks (each of BLOCK_SIZE bytes) */ #define ARGON2_MIN_MEMORY (2 * ARGON2_SYNC_POINTS) /* 2 blocks per slice */ #define ARGON2_MIN(a, b) ((a) < (b) ? (a) : (b)) /* Max memory size is half the addressing space, topping at 2^32 blocks (4 TB) */ #define ARGON2_MAX_MEMORY_BITS \ ARGON2_MIN(UINT32_C(32), (sizeof(void *) * CHAR_BIT - 10 - 1)) #define ARGON2_MAX_MEMORY \ ARGON2_MIN(UINT32_C(0xFFFFFFFF), UINT64_C(1) << ARGON2_MAX_MEMORY_BITS) /* Minimum and maximum number of passes */ #define ARGON2_MIN_TIME UINT32_C(3) #define ARGON2_MAX_TIME UINT32_C(0xFFFFFFFF) /* Minimum and maximum password length in bytes */ #define ARGON2_MIN_PWD_LENGTH UINT32_C(0) #define ARGON2_MAX_PWD_LENGTH UINT32_C(0xFFFFFFFF) /* Minimum and maximum associated data length in bytes */ #define ARGON2_MIN_AD_LENGTH UINT32_C(0) #define ARGON2_MAX_AD_LENGTH UINT32_C(0xFFFFFFFF) /* Minimum and maximum salt length in bytes */ #define ARGON2_MIN_SALT_LENGTH UINT32_C(8) #define ARGON2_MAX_SALT_LENGTH UINT32_C(0xFFFFFFFF) /* Minimum and maximum key length in bytes */ #define ARGON2_MIN_SECRET UINT32_C(0) #define ARGON2_MAX_SECRET UINT32_C(0xFFFFFFFF) #define ARGON2_FLAG_CLEAR_PASSWORD (UINT32_C(1) << 0) #define ARGON2_FLAG_CLEAR_SECRET (UINT32_C(1) << 1) #define ARGON2_FLAG_CLEAR_MEMORY (UINT32_C(1) << 2) #define ARGON2_DEFAULT_FLAGS (ARGON2_FLAG_CLEAR_MEMORY) /* Error codes */ typedef enum Argon2_ErrorCodes { ARGON2_OK = 0, ARGON2_OUTPUT_PTR_NULL = -1, ARGON2_OUTPUT_TOO_SHORT = -2, ARGON2_OUTPUT_TOO_LONG = -3, ARGON2_PWD_TOO_SHORT = -4, ARGON2_PWD_TOO_LONG = -5, ARGON2_SALT_TOO_SHORT = -6, ARGON2_SALT_TOO_LONG = -7, ARGON2_AD_TOO_SHORT = -8, ARGON2_AD_TOO_LONG = -9, ARGON2_SECRET_TOO_SHORT = -10, ARGON2_SECRET_TOO_LONG = -11, ARGON2_TIME_TOO_SMALL = -12, ARGON2_TIME_TOO_LARGE = -13, ARGON2_MEMORY_TOO_LITTLE = -14, ARGON2_MEMORY_TOO_MUCH = -15, ARGON2_LANES_TOO_FEW = -16, ARGON2_LANES_TOO_MANY = -17, ARGON2_PWD_PTR_MISMATCH = -18, /* NULL ptr with non-zero length */ ARGON2_SALT_PTR_MISMATCH = -19, /* NULL ptr with non-zero length */ ARGON2_SECRET_PTR_MISMATCH = -20, /* NULL ptr with non-zero length */ ARGON2_AD_PTR_MISMATCH = -21, /* NULL ptr with non-zero length */ ARGON2_MEMORY_ALLOCATION_ERROR = -22, ARGON2_FREE_MEMORY_CBK_NULL = -23, ARGON2_ALLOCATE_MEMORY_CBK_NULL = -24, ARGON2_INCORRECT_PARAMETER = -25, ARGON2_INCORRECT_TYPE = -26, ARGON2_OUT_PTR_MISMATCH = -27, ARGON2_THREADS_TOO_FEW = -28, ARGON2_THREADS_TOO_MANY = -29, ARGON2_MISSING_ARGS = -30, ARGON2_ENCODING_FAIL = -31, ARGON2_DECODING_FAIL = -32, ARGON2_THREAD_FAIL = -33, ARGON2_DECODING_LENGTH_FAIL = -34, ARGON2_VERIFY_MISMATCH = -35 } argon2_error_codes; /* Argon2 external data structures */ /* * Context: structure to hold Argon2 inputs: * output array and its length, * password and its length, * salt and its length, * secret and its length, * associated data and its length, * number of passes, amount of used memory (in KBytes, can be rounded up a bit) * number of parallel threads that will be run. * All the parameters above affect the output hash value. * Additionally, two function pointers can be provided to allocate and * deallocate the memory (if NULL, memory will be allocated internally). * Also, three flags indicate whether to erase password, secret as soon as they * are pre-hashed (and thus not needed anymore), and the entire memory ***** * Simplest situation: you have output array out[8], password is stored in * pwd[32], salt is stored in salt[16], you do not have keys nor associated data. * You need to spend 1 GB of RAM and you run 5 passes of Argon2 with 4 parallel lanes. * You want to erase the password, but you're OK with last pass not being erased. * You want to use the default memory allocator. * Then you initialize: * Argon2_Context(out,8,pwd,32,salt,16,NULL,0,NULL,0,5,1<<20,4,4,NULL,NULL,true,false,false,false). */ typedef struct Argon2_Context { uint8_t *out; /* output array */ uint32_t outlen; /* digest length */ uint8_t *pwd; /* password array */ uint32_t pwdlen; /* password length */ uint8_t *salt; /* salt array */ uint32_t saltlen; /* salt length */ uint8_t *secret; /* key array */ uint32_t secretlen; /* key length */ uint8_t *ad; /* associated data array */ uint32_t adlen; /* associated data length */ uint32_t t_cost; /* number of passes */ uint32_t m_cost; /* amount of memory requested (KB) */ uint32_t lanes; /* number of lanes */ uint32_t threads; /* maximum number of threads */ uint32_t flags; /* array of bool options */ } argon2_context; /* Argon2 primitive type */ typedef enum Argon2_type { Argon2_i = 1 } argon2_type; /* * Function that performs memory-hard hashing with certain degree of parallelism * @param context Pointer to the Argon2 internal structure * @return Error code if smth is wrong, ARGON2_OK otherwise */ int argon2_ctx(argon2_context *context, argon2_type type); /** * Hashes a password with Argon2i, producing an encoded hash * @param t_cost Number of iterations * @param m_cost Sets memory usage to m_cost kibibytes * @param parallelism Number of threads and compute lanes * @param pwd Pointer to password * @param pwdlen Password size in bytes * @param salt Pointer to salt * @param saltlen Salt size in bytes * @param hashlen Desired length of the hash in bytes * @param encoded Buffer where to write the encoded hash * @param encodedlen Size of the buffer (thus max size of the encoded hash) * @pre Different parallelism levels will give different results * @pre Returns ARGON2_OK if successful */ int argon2i_hash_encoded(const uint32_t t_cost, const uint32_t m_cost, const uint32_t parallelism, const void *pwd, const size_t pwdlen, const void *salt, const size_t saltlen, const size_t hashlen, char *encoded, const size_t encodedlen); /** * Hashes a password with Argon2i, producing a raw hash * @param t_cost Number of iterations * @param m_cost Sets memory usage to m_cost kibibytes * @param parallelism Number of threads and compute lanes * @param pwd Pointer to password * @param pwdlen Password size in bytes * @param salt Pointer to salt * @param saltlen Salt size in bytes * @param hash Buffer where to write the raw hash * @param hashlen Desired length of the hash in bytes * @pre Different parallelism levels will give different results * @pre Returns ARGON2_OK if successful */ int argon2i_hash_raw(const uint32_t t_cost, const uint32_t m_cost, const uint32_t parallelism, const void *pwd, const size_t pwdlen, const void *salt, const size_t saltlen, void *hash, const size_t hashlen); /* generic function underlying the above ones */ int argon2_hash(const uint32_t t_cost, const uint32_t m_cost, const uint32_t parallelism, const void *pwd, const size_t pwdlen, const void *salt, const size_t saltlen, void *hash, const size_t hashlen, char *encoded, const size_t encodedlen, argon2_type type); /** * Verifies a password against an encoded string * Encoded string is restricted as in validate_inputs() * @param encoded String encoding parameters, salt, hash * @param pwd Pointer to password * @pre Returns ARGON2_OK if successful */ int argon2i_verify(const char *encoded, const void *pwd, const size_t pwdlen); /* generic function underlying the above ones */ int argon2_verify(const char *encoded, const void *pwd, const size_t pwdlen, argon2_type type); #endif