Skip to content

wc_keystore.h

Functions

Name
int wc_KeyStore_ImportPlain(int devId, const byte * keyRef, word32 keyRefSz, word32 keyType, const byte * key, word32 keySz, word32 attrs, const void * ctx)
Place plaintext key material into a device's key store. This is the counterpart to wc_KeyStore_ImportWrapped for devices that accept a key in the clear; a device holding keys that may never appear in plaintext declines it and offers only the wrapped form.
int wc_KeyStore_ExportPlain(int devId, const byte * keyRef, word32 keyRefSz, byte * key, word32 * keySz, const void * ctx)
Read a stored key back as plaintext. Typically requires the key to have been created with WC_KEYSTORE_ATTR_EXPORTABLE, and many devices refuse this operation entirely; wc_KeyStore_ExportWrapped is the form that keeps the material inside the boundary.
int wc_KeyStore_ImportWrapped(int devId, const byte * keyRef, word32 keyRefSz, word32 keyType, const byte * wrapKeyRef, word32 wrapKeyRefSz, word32 format, const byte * blob, word32 blobSz, word32 attrs, const void * ctx)
Unwrap a key blob directly into a device's key store. The key material is never plaintext on this side of the boundary: the device unwraps it internally and the result exists only at keyRef.
int wc_KeyStore_ExportWrapped(int devId, const byte * keyRef, word32 keyRefSz, const byte * wrapKeyRef, word32 wrapKeyRefSz, word32 format, byte * blob, word32 * blobSz, const void * ctx)
Wrap a stored key under another stored key and emit the blob. Typically requires the key to have been created with WC_KEYSTORE_ATTR_EXPORTABLE, which is irrevocable on most hardware.
int wc_KeyStore_Derive(int devId, const byte * keyRef, word32 keyRefSz, word32 keyType, word32 keySz, const byte * srcKeyRef, word32 srcKeyRefSz, word32 kdfType, const byte * deriv, word32 derivSz, word32 attrs, const void * ctx)
Derive a new stored key from an existing one without either key touching RAM.
int wc_KeyStore_Delete(int devId, const byte * keyRef, word32 keyRefSz, const void * ctx)
Destroy a stored key. Deliberately separate from WC_ALGO_TYPE_FREE: freeing a wolfCrypt key object must never destroy the hardware key it refers to.
int wc_KeyStore_GetInfo(int devId, const byte * keyRef, word32 keyRefSz, word32 * keyType, word32 * keyBits, word32 * attrs, const void * ctx)
Report what a slot holds: key type, size in bits, and attributes.

Functions Documentation

function wc_KeyStore_ImportPlain

int wc_KeyStore_ImportPlain(
    int devId,
    const byte * keyRef,
    word32 keyRefSz,
    word32 keyType,
    const byte * key,
    word32 keySz,
    word32 attrs,
    const void * ctx
)

Place plaintext key material into a device's key store. This is the counterpart to wc_KeyStore_ImportWrapped for devices that accept a key in the clear; a device holding keys that may never appear in plaintext declines it and offers only the wrapped form.

Parameters:

  • devId crypto callback device ID
  • keyRef opaque reference naming where the key should land
  • keyRefSz length of keyRef in bytes
  • keyType what the key is for, from enum wc_KeyStoreKeyType
  • key plaintext key material
  • keySz length of key in bytes
  • attrs attributes for the key being created, WC_KEYSTORE_ATTR_*
  • ctx read-only caller context passed through to the device

See:

Return:

  • 0 on success
  • CRYPTOCB_UNAVAILABLE if no registered device handles the operation
  • BAD_FUNC_ARG if keyRef or key is NULL, or either size is zero

keyType says what the material is for, which is what lets the device set the stored key's properties: a raw byte string cannot tell an AES key from an HMAC key of the same length. It also fixes the encoding, so no further argument is needed to say: a symmetric type takes the raw key bytes, and an asymmetric type takes DER, a private key as PKCS#8 PrivateKeyInfo and a public key as SubjectPublicKeyInfo. keySz is the length of that encoding in bytes either way.

The caller owns the plaintext copy and should zeroize it once the import succeeds, for example with ForceZero().

Key references are opaque byte strings, interpreted only by the device. They are the same identifier WOLF_PRIVATE_KEY_ID uses, so the bytes that name a key here are the bytes wc_ecc_init_id() or wc_AesInit_Id() take to bind a wolfCrypt object to that key.

attrs sits at the end of the argument list rather than beside keyRef, because WC_KEYSTORE_ATTR_EXPORTABLE and WC_KEYSTORE_KEY_WRAP are both 1 and a swap between two adjacent control words would compile cleanly.

Example

byte keyRef[8];
byte aesKey[32];

ret = wc_KeyStore_ImportPlain(devId, keyRef, sizeof(keyRef),
                              WC_KEYSTORE_KEY_AES, aesKey, sizeof(aesKey),
                              WC_KEYSTORE_ATTR_PERSISTENT, NULL);
ForceZero(aesKey, sizeof(aesKey));
if (ret != 0) {
    // handle error
}

function wc_KeyStore_ExportPlain

int wc_KeyStore_ExportPlain(
    int devId,
    const byte * keyRef,
    word32 keyRefSz,
    byte * key,
    word32 * keySz,
    const void * ctx
)

Read a stored key back as plaintext. Typically requires the key to have been created with WC_KEYSTORE_ATTR_EXPORTABLE, and many devices refuse this operation entirely; wc_KeyStore_ExportWrapped is the form that keeps the material inside the boundary.

Parameters:

  • devId crypto callback device ID
  • keyRef opaque reference naming the key to export
  • keyRefSz length of keyRef in bytes
  • key buffer receiving the plaintext key, or NULL to query the size
  • keySz in: capacity of key in bytes, out: bytes written
  • ctx read-only caller context passed through to the device

See:

Return:

  • 0 on success
  • CRYPTOCB_UNAVAILABLE if no registered device handles the operation
  • BAD_FUNC_ARG if keyRef or keySz is NULL, keyRefSz is zero, or key is non-NULL with a zero capacity

The encoding matches wc_KeyStore_ImportPlain(): raw bytes for a symmetric key, DER for an asymmetric one. Call wc_KeyStore_GetInfo() to learn which the stored key is.

keySz is in/out: the capacity of key on entry, the number of bytes written on return. Passing key as NULL is a size query, which returns the size the device would produce through keySz. keySz is cleared first in that form, so any value passed in is discarded rather than preserved.

Call wc_KeyStore_GetInfo() first to learn whether the key is exportable, rather than attempting the export and interpreting the failure.

Example

byte   out[32];
word32 outSz = sizeof(out);

ret = wc_KeyStore_ExportPlain(devId, keyRef, sizeof(keyRef),
                              out, &outSz, NULL);
if (ret != 0) {
    // handle error
}

function wc_KeyStore_ImportWrapped

int wc_KeyStore_ImportWrapped(
    int devId,
    const byte * keyRef,
    word32 keyRefSz,
    word32 keyType,
    const byte * wrapKeyRef,
    word32 wrapKeyRefSz,
    word32 format,
    const byte * blob,
    word32 blobSz,
    word32 attrs,
    const void * ctx
)

Unwrap a key blob directly into a device's key store. The key material is never plaintext on this side of the boundary: the device unwraps it internally and the result exists only at keyRef.

Parameters:

  • devId crypto callback device ID
  • keyRef opaque reference naming where the key should land
  • keyRefSz length of keyRef in bytes
  • keyType what the wrapped key is for, from enum wc_KeyStoreKeyType, or WC_KEYSTORE_KEY_NONE to leave it to the container
  • wrapKeyRef opaque reference naming the wrapping key, or NULL when the device uses an implicit one
  • wrapKeyRefSz length of wrapKeyRef in bytes, zero when wrapKeyRef is NULL
  • format container format, from enum wc_KeyWrapFormat
  • blob the wrapped key blob
  • blobSz length of blob in bytes
  • attrs WC_KEYSTORE_ATTR_* for the key being created. Used only when the format carries no attributes of its own; a container that carries them wins and this is ignored. Call wc_KeyStore_GetInfo() afterwards to confirm what the import actually produced
  • ctx read-only caller context passed through to the device

See:

Return:

  • 0 on success
  • CRYPTOCB_UNAVAILABLE if no registered device handles the operation
  • BAD_FUNC_ARG if keyRef or blob is NULL, if either size is zero, or if wrapKeyRef is NULL with a non-zero wrapKeyRefSz

keyType says what the wrapped key is for. A bare RFC 3394 wrap (WC_KEYWRAP_FORMAT_AESKW) is a pure data transformation carrying no metadata, so for that format keyType is the device's only source. A vendor container that carries its own property word stays authoritative, and keyType is then a cross-check the device must refuse a mismatch on, since a mismatch means the right blob is going into the wrong kind of slot.

Key references are opaque byte strings, interpreted only by the device. They are the same identifier WOLF_PRIVATE_KEY_ID uses, so the bytes that name a key here are the bytes wc_ecc_init_id() or wc_AesInit_Id() take to bind a wolfCrypt object to that key.

Example

byte keyRef[8];
byte kekRef[8];

ret = wc_KeyStore_ImportWrapped(devId, keyRef, sizeof(keyRef),
                                WC_KEYSTORE_KEY_AES,
                                kekRef, sizeof(kekRef),
                                WC_KEYWRAP_FORMAT_AESKW,
                                blob, blobSz,
                                WC_KEYSTORE_ATTR_EXPORTABLE, NULL);
if (ret != 0) {
    // handle error
}

function wc_KeyStore_ExportWrapped

int wc_KeyStore_ExportWrapped(
    int devId,
    const byte * keyRef,
    word32 keyRefSz,
    const byte * wrapKeyRef,
    word32 wrapKeyRefSz,
    word32 format,
    byte * blob,
    word32 * blobSz,
    const void * ctx
)

Wrap a stored key under another stored key and emit the blob. Typically requires the key to have been created with WC_KEYSTORE_ATTR_EXPORTABLE, which is irrevocable on most hardware.

Parameters:

  • devId crypto callback device ID
  • keyRef opaque reference naming the key to wrap out
  • keyRefSz length of keyRef in bytes
  • wrapKeyRef opaque reference naming the wrapping key, or NULL when the device uses an implicit one
  • wrapKeyRefSz length of wrapKeyRef in bytes, zero when wrapKeyRef is NULL
  • format container format, from enum wc_KeyWrapFormat
  • blob buffer receiving the wrapped key, or NULL to query the size
  • blobSz in/out capacity then length, in bytes
  • ctx read-only caller context passed through to the device

See:

Return:

  • 0 on success
  • CRYPTOCB_UNAVAILABLE if no registered device handles the operation
  • BAD_FUNC_ARG if keyRef or blobSz is NULL, if keyRefSz is zero, if blob is non-NULL with a zero capacity, or if wrapKeyRef is NULL with a non-zero wrapKeyRefSz

blobSz is in/out: the capacity of blob on entry, the number of bytes written on return. Passing blob as NULL is a size query, which returns the size the device would produce through blobSz. blobSz is cleared first in that form, so any value passed in is discarded rather than preserved.

Example

word32 blobSz = 0;

// ask how large the container will be
ret = wc_KeyStore_ExportWrapped(devId, keyRef, sizeof(keyRef),
                                kekRef, sizeof(kekRef),
                                WC_KEYWRAP_FORMAT_AESKW,
                                NULL, &blobSz, NULL);

function wc_KeyStore_Derive

int wc_KeyStore_Derive(
    int devId,
    const byte * keyRef,
    word32 keyRefSz,
    word32 keyType,
    word32 keySz,
    const byte * srcKeyRef,
    word32 srcKeyRefSz,
    word32 kdfType,
    const byte * deriv,
    word32 derivSz,
    word32 attrs,
    const void * ctx
)

Derive a new stored key from an existing one without either key touching RAM.

Parameters:

  • devId crypto callback device ID
  • keyRef opaque reference naming where the derived key should land
  • keyRefSz length of keyRef in bytes
  • keyType what the derived key is for, from enum wc_KeyStoreKeyType, or WC_KEYSTORE_KEY_NONE to leave it to the device
  • keySz size in bytes of the key to create, or 0 to leave it to the device. Unlike the other operations there is nothing else to infer it from: the derivation data length is the input's, not the output's
  • srcKeyRef opaque reference naming the derivation key
  • srcKeyRefSz length of srcKeyRef in bytes
  • kdfType derivation function, from enum wc_KdfType. WC_KDF_TYPE_NONE asks for the device's own derivation, which is all many key stores offer
  • deriv derivation data
  • derivSz length of deriv in bytes, often fixed by the hardware
  • attrs WC_KEYSTORE_ATTR_* requested for the key being created
  • ctx read-only caller context passed through to the device

See: wc_KeyStore_GetInfo

Return:

  • 0 on success
  • CRYPTOCB_UNAVAILABLE if no registered device handles the operation
  • BAD_FUNC_ARG if keyRef or srcKeyRef is NULL, if keyRefSz or srcKeyRefSz is zero, or if deriv is NULL with a non-zero derivSz. A zero derivSz is legal: it is the form used when the KDF takes no extra input

Nothing in a derivation says what its result is for, so keyType does. A device that encodes the key's purpose inside its own key references may treat this as a cross-check, but it must not require that, since a reference is opaque to wolfCrypt and need carry no such field.

Argument order follows the rule used throughout this API: no two interchangeable control words sit next to each other. keyType names the key being created and follows its reference, kdfType precedes the derivation data, and attrs moves to the tail rather than sit beside keyType, since WC_KEYSTORE_ATTR_EXPORTABLE and WC_KEYSTORE_KEY_WRAP are both 1.

Example

ret = wc_KeyStore_Derive(devId, keyRef, sizeof(keyRef),
                         WC_KEYSTORE_KEY_AES, AES_256_KEY_SIZE,
                         parentRef, sizeof(parentRef),
                         WC_KDF_TYPE_NONE, deriv, sizeof(deriv),
                         WC_KEYSTORE_ATTR_EXPORTABLE, NULL);

function wc_KeyStore_Delete

int wc_KeyStore_Delete(
    int devId,
    const byte * keyRef,
    word32 keyRefSz,
    const void * ctx
)

Destroy a stored key. Deliberately separate from WC_ALGO_TYPE_FREE: freeing a wolfCrypt key object must never destroy the hardware key it refers to.

Parameters:

  • devId crypto callback device ID
  • keyRef opaque reference naming the key to destroy
  • keyRefSz length of keyRef in bytes
  • ctx read-only caller context passed through to the device

See: wc_KeyStore_ImportWrapped

Return:

  • 0 on success
  • CRYPTOCB_UNAVAILABLE if no registered device handles the operation
  • BAD_FUNC_ARG if keyRef is NULL or keyRefSz is zero

Example

ret = wc_KeyStore_Delete(devId, keyRef, sizeof(keyRef), NULL);

function wc_KeyStore_GetInfo

int wc_KeyStore_GetInfo(
    int devId,
    const byte * keyRef,
    word32 keyRefSz,
    word32 * keyType,
    word32 * keyBits,
    word32 * attrs,
    const void * ctx
)

Report what a slot holds: key type, size in bits, and attributes.

Parameters:

  • devId crypto callback device ID
  • keyRef opaque reference naming the key to query
  • keyRefSz length of keyRef in bytes
  • keyType out, a value from enum wc_KeyStoreKeyType
  • keyBits out, key size in bits
  • attrs out, WC_KEYSTORE_ATTR_* the key carries
  • ctx read-only caller context passed through to the device

See:

Return:

  • 0 on success
  • CRYPTOCB_UNAVAILABLE if no registered device handles the operation
  • BAD_FUNC_ARG if keyRef is NULL or keyRefSz is zero

Any WC_KEYSTORE_ATTR_* the device can represent is reported here, so a caller can ask whether an export is permitted rather than attempting one and interpreting the failure. Attributes the device cannot represent read as absent, and out parameters the device does not fill are cleared rather than left holding the caller's stack.

Example

word32 keyType = 0, keyBits = 0, attrs = 0;

ret = wc_KeyStore_GetInfo(devId, keyRef, sizeof(keyRef),
                          &keyType, &keyBits, &attrs, NULL);
if (ret == 0 && (attrs & WC_KEYSTORE_ATTR_EXPORTABLE)) {
    // the key may be wrapped out
}

Source code


int wc_KeyStore_ImportPlain(int devId,
    const byte* keyRef, word32 keyRefSz,
    word32 keyType, const byte* key, word32 keySz,
    word32 attrs, const void* ctx);

int wc_KeyStore_ExportPlain(int devId,
    const byte* keyRef, word32 keyRefSz,
    byte* key, word32* keySz, const void* ctx);

int wc_KeyStore_ImportWrapped(int devId,
    const byte* keyRef, word32 keyRefSz, word32 keyType,
    const byte* wrapKeyRef, word32 wrapKeyRefSz,
    word32 format, const byte* blob, word32 blobSz,
    word32 attrs, const void* ctx);

int wc_KeyStore_ExportWrapped(int devId,
    const byte* keyRef, word32 keyRefSz,
    const byte* wrapKeyRef, word32 wrapKeyRefSz,
    word32 format, byte* blob, word32* blobSz, const void* ctx);

int wc_KeyStore_Derive(int devId,
    const byte* keyRef, word32 keyRefSz, word32 keyType, word32 keySz,
    const byte* srcKeyRef, word32 srcKeyRefSz,
    word32 kdfType, const byte* deriv, word32 derivSz,
    word32 attrs, const void* ctx);

int wc_KeyStore_Delete(int devId, const byte* keyRef, word32 keyRefSz,
    const void* ctx);

int wc_KeyStore_GetInfo(int devId, const byte* keyRef, word32 keyRefSz,
    word32* keyType, word32* keyBits, word32* attrs, const void* ctx);

Updated on 2026-11-13 at 01:20:07 +0000