P1363 KDF2

From Crypto++ Wiki
Jump to navigation Jump to search
P1363_KDF2
Documentation
#include <cryptopp/pubkey.h>

P1363_KDF2 is an early key derivation function (KDF) specified by P1363 and used in mask generation functions. The function takes a secret seed and derivation parameters and outputs key material.

P1363_KDF2 derives from KeyDerivationFunction interface. P1363_KDF2 provides two DeriveKey member functions. The first member function is required by KeyDerivationFunction and accepts a NameValuePairs object to pass arbitrary parameters. The second DeriveKey overload provides a specialized DeriveKey with parameters tuned for P1363_KDF2.

P1363_KDF2 is an older standard. Early KDFs from the bygone era include P1363_KDF2, PKCS12_PBKDF, PKCS5_PBKDF1 and PKCS5_PBKDF2_HMAC. New applications should consider using a modern KDF, like HKDF. HKDF is state of the art extract-then-expand derivation function with provable security properties.

Constructor

P1363_KDF2 provides a default constructor.

DeriveKey

unsigned int DeriveKey (byte *derived, size_t derivedLen,
                        const byte *secret, size_t secretLen,
                        const byte *derivationParams, size_t derivationParamsLen

derived is the buffer to receive the derived key. derivedLen is the size of the buffer, in bytes.

secret is private information to use during derivation. secretLen is the size of the buffer, in bytes.

derivationParams is possibly public information to use during derivation. derivationParamsLen is the size of the buffer, in bytes.

DeriveKey returns the number of iteration.

derivationParams is used to help distinguish one instance or run of the algorithm from another. The parameters can be NULL.


Sample Program

The sample program below demonstrates a P1363_KDF2 with SHA256.

$ cat test.cxx
#include <iostream>
#include <string>

#include "cryptlib.h"
#include "pubkey.h"
#include "sha.h"
#include "hex.h"

int main(int argc, char* argv[])
{
    using namespace CryptoPP;

    byte password[] ="password";
    size_t plen = strlen((const char*)password);

    byte derivation[] = "derivation";
    size_t dlen = strlen((const char*)derivation);

    byte derived[SHA256::DIGESTSIZE];

    P1363_KDF2<SHA256> pbkdf;
    pbkdf.DeriveKey(derived, sizeof(derived), purpose, password, plen, derivation, dlen);

    std::string result;
    HexEncoder encoder(new StringSink(result));

    encoder.Put(derived, sizeof(derived));
    encoder.MessageEnd();

    std::cout << "Derived: " << result << std::endl;

    return 0;
}

Running the program results in the following.

$ ./test.exe
Derived: 2AAB4F1F55674E2E7519C0C57623D69921C68C1D7315B502DD91771C1B57DFAB

You can swap-in any hash class that provides a blocksize. The code below uses BLAKE2b as the message digest. The BLAKE2b sample below requires Commit 758939ab2e1b.

$ cat test.cxx
#include <iostream>
#include <string>

#include "cryptlib.h"
#include "pubkey.h"
#include "blake2.h"
#include "hex.h"

int main(int argc, char* argv[])
{
    using namespace CryptoPP;

    byte password[] ="password";
    size_t plen = strlen((const char*)password);

    byte derivation[] = "derivation";
    size_t dlen = strlen((const char*)derivation);

    byte derived[BLAKE2b::DIGESTSIZE];

    P1363_KDF2<BLAKE2b> pbkdf;
    pbkdf.DeriveKey(derived, sizeof(derived), password, plen, derivation, dlen);

    std::string result;
    HexEncoder encoder(new StringSink(result));

    encoder.Put(derived, sizeof(derived));
    encoder.MessageEnd();

    std::cout << "Derived: " << result << std::endl;

    return 0;
}

Running the program results in the following.

$ ./test.exe
Derived: 44443035E50DA34B58565645332D2DF1360C9D66E79FB0B4D283B99B7D23D121A0B0E5A
0F82783820C2B73D1A3412A311E9EC8CA1CFC822599DF99BBDDBBB126

The sample program below demonstrates a P1363_KDF2 with SHA256, and uses the derived material to key a block cipher. Notice two different labels are used. First, the label P1363_KDF2 key derivation to derive the key; and second, the label P1363_KDF2 iv derivation to derive the initialization vector.

$ cat test.cxx
#include <iostream>
#include <string>

#include "cryptlib.h"
#include "pubkey.h"
#include "sha.h"
#include "files.h"
#include "aes.h"
#include "modes.h"
#include "hex.h"

int main(int argc, char* argv[])
{
    using namespace CryptoPP;

    byte password[] ="password";
    size_t plen = strlen((const char*)password);

    byte derive1[] = "P1363_KDF2 key derivation";
    size_t dlen1 = strlen((const char*)derive1);

    byte derive2[] = "P1363_KDF2 iv derivation";
    size_t dlen2 = strlen((const char*)derive2);

    byte key[AES::DEFAULT_KEYLENGTH];
    byte iv[AES::BLOCKSIZE];

    P1363_KDF2<SHA256> pbkdf;

    pbkdf.DeriveKey(key, sizeof(key), password, plen, derive1, dlen1);
    pbkdf.DeriveKey(iv, sizeof(iv), password, plen, derive2, dlen2);

    std::cout << "Key: ";
    StringSource(key, sizeof(key), true, new HexEncoder(new FileSink(std::cout)));
    std::cout << std::endl;

    std::cout << "IV: ";
    StringSource(iv, sizeof(iv), true, new HexEncoder(new FileSink(std::cout)));
    std::cout << std::endl;

    CBC_Mode<AES>::Encryption enc;
    enc.SetKeyWithIV(key, sizeof(key), iv, sizeof(iv));

    // Use AES/CBC encryptor

    return 0;
}

Running the program results in the following.

$ ./test.exe 
Key: 346BFA96578DC2ADFE2B7767C3F09985
IV: 709983BB8FD593B4B08E62156EE5F9A2

Downloads

No downloads.