Derive an encryption key

Derive an encryption key to secure communication between devices using the Terminal API.

Steps

Two parties who wish to derive a key must:

  1. Share a variable length secret to derive the key material. 
  2. Derive the key using PBKDF2_HMAC_SHA1
  3. Include the following parameters:

    Parameter Value
    salt AdyenNexoV1Salt
    salt length

    15;

    rounds 4000;

    If the program saves the resulting derived key, this computation is performed once for each shared secret.

    The derived key material consists of 80 bytes: a 32 byte cipher key, a 32 byte HMAC key and a 16 byte initialization vector (IV). The IV is XORed with a random nonce that is generated per message on encryption. 

    A derived key is identified by both its KeyIdentifier and its version.

Code example

Example C code using OpenSSL to derive the key material:

/* The struct to hold the derived keys is defined like so: */
 
struct nexo_derived_keys {
    uint8_t hmac_key[NEXO_HMAC_KEY_LENGTH];
    uint8_t cipher_key[NEXO_CIPHER_KEY_LENGTH];
    uint8_t iv[NEXO_IV_LENGTH];
};

/* Function to derive the keys: */
int nexo_derive_key_material(const char * passphrase, size_t len, struct nexo_derived_keys *dk) {
    const unsigned char salt[] = "AdyenNexoV1Salt";
    const int saltlen = sizeof(salt) - 1;
    const int rounds = 4000;
    return PKCS5_PBKDF2_HMAC_SHA1(passphrase, len, salt, saltlen, rounds,
             sizeof(struct nexo_derived_keys), (unsigned char *)dk);

}