argon2.h
Functions
| Name | |
|---|---|
| int | wc_Argon2Init(Argon2Ctx * a, void * heap, int devId) This function initializes an Argon2 context. No memory is allocated: the block array is sized by the cost parameters and is allocated by wc_Argon2SetParams(). Every context must be released with wc_Argon2Free(). |
| void | wc_Argon2Free(Argon2Ctx * a) This function releases the resources held by an Argon2 context. The block array holds the whole of the secret state and is wiped before being returned to the allocator. Safe to call on a context whose parameters were never set, and safe to call more than once. |
| Argon2Ctx * | wc_Argon2New(void * heap, int devId, int * result_code) This function allocates and initializes a new Argon2 context. The returned context has no parameters set; call wc_Argon2SetParams() before wc_Argon2DeriveTag(). Release it with wc_Argon2Delete(). |
| int | wc_Argon2Delete(Argon2Ctx * a, Argon2Ctx ** a_p) This function frees an Argon2 context created with wc_Argon2New(), wiping the block array, and sets the caller's pointer to NULL. |
| int | wc_Argon2SetParams(Argon2Ctx * a, int type, word32 parallel, word32 memCost, word32 timeCost) This function sets the variant and cost parameters on an Argon2 context and allocates the block array. It may be called again to change the parameters; the existing allocation is kept when the new parameters need a block array of the same size. |
| int | wc_Argon2SetThreads(Argon2Ctx * a, word32 threads) This function sets the number of threads used to fill the segments of a slice. Only available when WOLFSSL_ARGON2_THREADS is defined, which the –enable-argon2-threads configure option does. |
| int | wc_Argon2DeriveTag(Argon2Ctx * a, byte * out, word32 outSz, const byte * pwd, word32 pwdSz, const byte * salt, word32 saltSz, const byte * secret, word32 secretSz, const byte * ad, word32 adSz) This function derives a key using the parameters already set on the context with wc_Argon2SetParams(). The context may be reused for any number of derivations; no allocation is performed here. |
| int | wc_Argon2(int type, byte * out, word32 outSz, const byte * pwd, word32 pwdSz, const byte * salt, word32 saltSz, word32 parallel, word32 memCost, word32 timeCost) This function derives a key from a password using Argon2, the memory-hard password hashing function specified in RFC 9106. Version 0x13 is used; the superseded 0x10 encoding is not supported. |
| int | wc_Argon2_ex(int type, byte * out, word32 outSz, const byte * pwd, word32 pwdSz, const byte * salt, word32 saltSz, const byte * secret, word32 secretSz, const byte * ad, word32 adSz, word32 parallel, word32 memCost, word32 timeCost, void * heap) This function derives a key from a password using Argon2, as wc_Argon2() does, additionally accepting the optional secret value K and associated data X of RFC 9106, and a heap hint for the memory allocation. |
Functions Documentation
function wc_Argon2Init
int wc_Argon2Init(
Argon2Ctx * a,
void * heap,
int devId
)
This function initializes an Argon2 context. No memory is allocated: the block array is sized by the cost parameters and is allocated by wc_Argon2SetParams(). Every context must be released with wc_Argon2Free().
Parameters:
- a pointer to the Argon2 context to initialize.
- heap heap hint passed to XMALLOC; may be NULL.
- devId device identifier; reserved for future use, pass INVALID_DEVID.
See:
Return:
- 0 on success.
- BAD_FUNC_ARG if a is NULL.
Use the context API in preference to wc_Argon2() when deriving many tags with the same cost parameters, so that the block array - which may be tens or hundreds of megabytes - is allocated only once.
Example
Argon2Ctx a;
byte key[32];
if (wc_Argon2Init(&a, NULL, INVALID_DEVID) != 0)
// handle error
if (wc_Argon2SetParams(&a, WC_ARGON2_ID, 4, 65536, 3) != 0)
// handle error
if (wc_Argon2DeriveTag(&a, key, sizeof(key), pwd, pwdSz, salt, saltSz,
NULL, 0, NULL, 0) != 0)
// handle error
wc_Argon2Free(&a);
function wc_Argon2Free
void wc_Argon2Free(
Argon2Ctx * a
)
This function releases the resources held by an Argon2 context. The block array holds the whole of the secret state and is wiped before being returned to the allocator. Safe to call on a context whose parameters were never set, and safe to call more than once.
Parameters:
- a pointer to the Argon2 context to free; may be NULL.
See: wc_Argon2Init
Return: none No returns.
Example
Argon2Ctx a;
if (wc_Argon2Init(&a, NULL, INVALID_DEVID) != 0)
// handle error
...
wc_Argon2Free(&a);
function wc_Argon2New
Argon2Ctx * wc_Argon2New(
void * heap,
int devId,
int * result_code
)
This function allocates and initializes a new Argon2 context. The returned context has no parameters set; call wc_Argon2SetParams() before wc_Argon2DeriveTag(). Release it with wc_Argon2Delete().
Parameters:
- heap heap hint passed to XMALLOC; may be NULL.
- devId device identifier; reserved for future use, pass INVALID_DEVID.
- result_code pointer to hold the result of the operation; may be NULL.
See:
Return:
- pointer to the new Argon2 context on success.
- NULL if the allocation fails, with result_code set to MEMORY_E when it is not NULL.
Only available when WC_NO_CONSTRUCTORS is not defined.
Example
Argon2Ctx* a;
int ret;
a = wc_Argon2New(NULL, INVALID_DEVID, &ret);
if (a == NULL)
// handle error, ret holds the reason
if (wc_Argon2SetParams(a, WC_ARGON2_ID, 4, 65536, 3) != 0)
// handle error
...
wc_Argon2Delete(a, &a);
function wc_Argon2Delete
int wc_Argon2Delete(
Argon2Ctx * a,
Argon2Ctx ** a_p
)
This function frees an Argon2 context created with wc_Argon2New(), wiping the block array, and sets the caller's pointer to NULL.
Parameters:
- a pointer to the Argon2 context to delete.
- a_p pointer to the context pointer, set to NULL; may be NULL.
See: wc_Argon2New
Return:
- 0 on success.
- BAD_FUNC_ARG if a is NULL.
Only available when WC_NO_CONSTRUCTORS is not defined.
Example
Argon2Ctx* a = wc_Argon2New(NULL, INVALID_DEVID, NULL);
...
if (wc_Argon2Delete(a, &a) != 0)
// handle error
// a is now NULL
function wc_Argon2SetParams
int wc_Argon2SetParams(
Argon2Ctx * a,
int type,
word32 parallel,
word32 memCost,
word32 timeCost
)
This function sets the variant and cost parameters on an Argon2 context and allocates the block array. It may be called again to change the parameters; the existing allocation is kept when the new parameters need a block array of the same size.
Parameters:
- a pointer to the Argon2 context.
- type variant to use: WC_ARGON2_D, WC_ARGON2_I or WC_ARGON2_ID.
- parallel degree of parallelism p (number of lanes).
- memCost memory size m in KiB; must be at least 8 * parallel. It is rounded down internally to a multiple of 4 * parallel.
- timeCost number of passes t over the memory, at least 1.
See:
Return:
- 0 on success.
- BAD_FUNC_ARG if a is NULL, if type is not one of the three variants, if parallel or timeCost is zero, if parallel exceeds WC_ARGON2_MAX_LANES, or if memCost is below 8 * parallel.
- MEMORY_E if the block array could not be allocated.
See wc_Argon2() for guidance on choosing the variant and the cost parameters.
Example
Argon2Ctx a;
if (wc_Argon2Init(&a, NULL, INVALID_DEVID) != 0)
// handle error
// Argon2id, p = 4 lanes, m = 64 MiB, t = 3 passes
if (wc_Argon2SetParams(&a, WC_ARGON2_ID, 4, 65536, 3) != 0)
// handle error
function wc_Argon2SetThreads
int wc_Argon2SetThreads(
Argon2Ctx * a,
word32 threads
)
This function sets the number of threads used to fill the segments of a slice. Only available when WOLFSSL_ARGON2_THREADS is defined, which the –enable-argon2-threads configure option does.
Parameters:
- a pointer to the Argon2 context.
- threads number of threads to use, at least 1.
See:
Return:
- 0 on success.
- BAD_FUNC_ARG if a is NULL, or threads is 0 or above WC_ARGON2_MAX_THREADS.
- MEMORY_E if the per-thread working state could not be allocated.
The p segments of a slice are independent, so up to p of them can be filled at once. A count above the lane count is accepted but allocates no more workers than there are lanes, since the extra ones could never be given work. A count of 1 spawns no threads at all: one segment of every batch is always filled by the calling thread.
This does not change the tag. The synchronization point at the end of every slice makes the result the same however many threads fill it, so a tag derived with one thread and the same tag derived with eight are identical.
Changing the count reallocates the per-thread working state, so prefer to set it once before deriving.
Example
Argon2Ctx a;
byte key[32];
if (wc_Argon2Init(&a, NULL, INVALID_DEVID) != 0)
// handle error
// Argon2id, p = 4 lanes, m = 64 MiB, t = 3 passes, filled by 4 threads
if (wc_Argon2SetThreads(&a, 4) != 0)
// handle error
if (wc_Argon2SetParams(&a, WC_ARGON2_ID, 4, 65536, 3) != 0)
// handle error
if (wc_Argon2DeriveTag(&a, key, sizeof(key), pwd, pwdSz, salt, saltSz,
NULL, 0, NULL, 0) != 0)
// handle error
wc_Argon2Free(&a);
function wc_Argon2DeriveTag
int wc_Argon2DeriveTag(
Argon2Ctx * a,
byte * out,
word32 outSz,
const byte * pwd,
word32 pwdSz,
const byte * salt,
word32 saltSz,
const byte * secret,
word32 secretSz,
const byte * ad,
word32 adSz
)
This function derives a key using the parameters already set on the context with wc_Argon2SetParams(). The context may be reused for any number of derivations; no allocation is performed here.
Parameters:
- a pointer to the Argon2 context with parameters set.
- out buffer to hold the derived key (the "tag").
- outSz length of out in bytes, at least WC_ARGON2_MIN_OUTLEN.
- pwd password to derive from; may be NULL only when pwdSz is 0.
- pwdSz length of pwd in bytes.
- salt salt to derive with; should be unique per password.
- saltSz length of salt in bytes, at least WC_ARGON2_MIN_SALT_LEN.
- secret optional secret value K; NULL when unused.
- secretSz length of secret in bytes, 0 when unused.
- ad optional associated data X; NULL when unused.
- adSz length of ad in bytes, 0 when unused.
See:
Return:
- 0 on success.
- BAD_FUNC_ARG if a, out or salt is NULL, or if pwd, secret or ad is NULL while its length is non-zero.
- BAD_STATE_E if wc_Argon2SetParams() has not been called.
- BAD_LENGTH_E if outSz is below WC_ARGON2_MIN_OUTLEN or saltSz is below WC_ARGON2_MIN_SALT_LEN.
The optional secret K (secret/secretSz) and associated data X (ad/adSz) of RFC 9106 are accepted, as for wc_Argon2_ex(). Pass NULL and 0 when they are unused.
Example
Argon2Ctx a;
byte key[32];
int i;
if (wc_Argon2Init(&a, NULL, INVALID_DEVID) != 0)
// handle error
if (wc_Argon2SetParams(&a, WC_ARGON2_ID, 4, 65536, 3) != 0)
// handle error
// The block array is allocated once and reused for every password.
for (i = 0; i < numPasswords; i++) {
if (wc_Argon2DeriveTag(&a, key, sizeof(key), pwd[i], pwdSz[i],
salt[i], saltSz[i], NULL, 0, NULL, 0) != 0)
// handle error
}
wc_Argon2Free(&a);
function wc_Argon2
int wc_Argon2(
int type,
byte * out,
word32 outSz,
const byte * pwd,
word32 pwdSz,
const byte * salt,
word32 saltSz,
word32 parallel,
word32 memCost,
word32 timeCost
)
This function derives a key from a password using Argon2, the memory-hard password hashing function specified in RFC 9106. Version 0x13 is used; the superseded 0x10 encoding is not supported.
Parameters:
- type variant to use: WC_ARGON2_D, WC_ARGON2_I or WC_ARGON2_ID.
- out buffer to hold the derived key (the "tag").
- outSz length of out in bytes, at least WC_ARGON2_MIN_OUTLEN.
- pwd password to derive from; may be NULL only when pwdSz is 0.
- pwdSz length of pwd in bytes.
- salt salt to derive with; should be unique per password.
- saltSz length of salt in bytes, at least WC_ARGON2_MIN_SALT_LEN.
- parallel degree of parallelism p (number of lanes).
- memCost memory size m in KiB; must be at least 8 * parallel. It is rounded down internally to a multiple of 4 * parallel.
- timeCost number of passes t over the memory, at least 1.
See:
Return:
- 0 on success.
- BAD_FUNC_ARG if out or salt is NULL, if pwd is NULL while pwdSz is non-zero, if type is not one of the three variants, if parallel or timeCost is zero, if parallel exceeds WC_ARGON2_MAX_LANES, or if memCost is below 8 * parallel.
- BAD_LENGTH_E if outSz is below WC_ARGON2_MIN_OUTLEN or saltSz is below WC_ARGON2_MIN_SALT_LEN.
- MEMORY_E if the memory block array could not be allocated.
Pick the variant to suit the threat model: WC_ARGON2_ID is the choice RFC 9106 recommends when there is no reason to prefer another, since it resists both side-channel and time-memory trade-off attacks. WC_ARGON2_I resists side-channel attacks but is weaker against trade-off attacks, and WC_ARGON2_D the reverse; WC_ARGON2_D should not be used where an attacker may observe memory access patterns.
RFC 9106 section 4 recommends t=3 and p=4 with m=65536 (64 MiB) if 64 MiB is available, or t=1 and p=4 with m=2097152 (2 GiB) for the highest-security setting. Cost parameters should be raised to the most the application can tolerate.
Example
byte key[32];
byte salt[16];
const char* password = "correct horse battery staple";
if (wc_RNG_GenerateBlock(&rng, salt, sizeof(salt)) != 0)
// handle error
// Argon2id, p = 4 lanes, m = 64 MiB, t = 3 passes
if (wc_Argon2(WC_ARGON2_ID, key, sizeof(key),
(const byte*)password, (word32)XSTRLEN(password),
salt, sizeof(salt), 4, 65536, 3) != 0)
// handle error
When built with WOLFSSL_ARGON2_THREADS this fills the segments of a slice on one thread per lane, which does not change the derived key. Use the context API with wc_Argon2SetThreads() to choose a different number of threads.
function wc_Argon2_ex
int wc_Argon2_ex(
int type,
byte * out,
word32 outSz,
const byte * pwd,
word32 pwdSz,
const byte * salt,
word32 saltSz,
const byte * secret,
word32 secretSz,
const byte * ad,
word32 adSz,
word32 parallel,
word32 memCost,
word32 timeCost,
void * heap
)
This function derives a key from a password using Argon2, as wc_Argon2() does, additionally accepting the optional secret value K and associated data X of RFC 9106, and a heap hint for the memory allocation.
Parameters:
- type variant to use: WC_ARGON2_D, WC_ARGON2_I or WC_ARGON2_ID.
- out buffer to hold the derived key (the "tag").
- outSz length of out in bytes, at least WC_ARGON2_MIN_OUTLEN.
- pwd password to derive from; may be NULL only when pwdSz is 0.
- pwdSz length of pwd in bytes.
- salt salt to derive with; should be unique per password.
- saltSz length of salt in bytes, at least WC_ARGON2_MIN_SALT_LEN.
- secret optional secret value K; NULL when unused.
- secretSz length of secret in bytes, 0 when unused.
- ad optional associated data X; NULL when unused.
- adSz length of ad in bytes, 0 when unused.
- parallel degree of parallelism p (number of lanes).
- memCost memory size m in KiB; must be at least 8 * parallel.
- timeCost number of passes t over the memory, at least 1.
- heap heap hint passed to XMALLOC; may be NULL.
See:
Return:
- 0 on success.
- BAD_FUNC_ARG on the same conditions as wc_Argon2(), or if secret or ad is NULL while its length is non-zero.
- BAD_LENGTH_E if outSz is below WC_ARGON2_MIN_OUTLEN or saltSz is below WC_ARGON2_MIN_SALT_LEN.
- MEMORY_E if the memory block array could not be allocated.
The secret K is a key not stored alongside the hash — often called a pepper — which prevents an attacker who has stolen only the hash database from mounting an offline guessing attack. The associated data X binds the tag to extra context, such as a user name.
Example
byte key[32];
byte salt[16];
byte pepper[16];
const char* password = "correct horse battery staple";
const char* user = "alice";
// Argon2id, p = 4 lanes, m = 64 MiB, t = 3 passes
if (wc_Argon2_ex(WC_ARGON2_ID, key, sizeof(key),
(const byte*)password, (word32)XSTRLEN(password),
salt, sizeof(salt),
pepper, sizeof(pepper),
(const byte*)user, (word32)XSTRLEN(user),
4, 65536, 3, NULL) != 0)
// handle error
When built with WOLFSSL_ARGON2_THREADS this fills the segments of a slice on one thread per lane, which does not change the derived key. Use the context API with wc_Argon2SetThreads() to choose a different number of threads.
Source code
int wc_Argon2Init(Argon2Ctx* a, void* heap, int devId);
void wc_Argon2Free(Argon2Ctx* a);
Argon2Ctx* wc_Argon2New(void* heap, int devId, int* result_code);
int wc_Argon2Delete(Argon2Ctx* a, Argon2Ctx** a_p);
int wc_Argon2SetParams(Argon2Ctx* a, int type, word32 parallel,
word32 memCost, word32 timeCost);
int wc_Argon2SetThreads(Argon2Ctx* a, word32 threads);
int wc_Argon2DeriveTag(Argon2Ctx* a, byte* out, word32 outSz,
const byte* pwd, word32 pwdSz, const byte* salt, word32 saltSz,
const byte* secret, word32 secretSz, const byte* ad, word32 adSz);
int wc_Argon2(int type, byte* out, word32 outSz,
const byte* pwd, word32 pwdSz,
const byte* salt, word32 saltSz,
word32 parallel, word32 memCost, word32 timeCost);
int wc_Argon2_ex(int type, byte* out, word32 outSz,
const byte* pwd, word32 pwdSz,
const byte* salt, word32 saltSz,
const byte* secret, word32 secretSz,
const byte* ad, word32 adSz,
word32 parallel, word32 memCost, word32 timeCost,
void* heap);
Updated on 2026-11-13 at 01:20:07 +0000