Cryptography API

For convenience, CCF provides access to commonly used cryptographic primitives to applications.

Note

This page describes the C++ API. For the API for TypeScript/JavaScript applications, see ccf-app/crypto.

Hashing

std::vector<uint8_t> ccf::crypto::sha256(const std::vector<uint8_t> &data)
HashBytes ccf::crypto::hmac(MDType type, const std::vector<uint8_t> &key, const std::vector<uint8_t> &data)

Compute the HMAC of key and data

class HashProvider

Subclassed by ccf::crypto::OpenSSLHashProvider

Public Functions

virtual HashBytes Hash(const uint8_t *data, size_t size, MDType type) const = 0

Generic Hash function

Parameters:
  • data – The data to hash

  • size – The size of data

  • type – The type of hash to compute

std::shared_ptr<HashProvider> ccf::crypto::make_hash_provider()

Create a default hash provider

Asymmetric Keys

CCF supports EC and RSA keys; public keys are held in (RSA)PublicKey objects and private keys in (RSA)KeyPair objects. (RSA)KeyPairs automatically generate random keys when constructed via KeyPairPtr ccf::crypto::make_key_pair(CurveID) or RSAKeyPairPtr ccf::crypto::make_rsa_key_pair(size_t, size_t).

class PublicKey

Subclassed by ccf::crypto::PublicKey_OpenSSL

Public Functions

virtual bool verify(const uint8_t *contents, size_t contents_size, const uint8_t *sig, size_t sig_size, MDType md_type, HashBytes &bytes) = 0

Verify that a signature was produced on contents with the private key associated with the public key held by the object.

Parameters:
  • contents – address of contents

  • contents_size – size of contents

  • sig – address of signature

  • sig_size – size of signature

  • md_type – Digest algorithm to use

  • bytes – Buffer to write the hash to

Returns:

Whether the signature matches the contents and the key

inline bool verify(const uint8_t *contents, size_t contents_size, const uint8_t *sig, size_t sig_size, MDType md_type = MDType::NONE)

Verify that a signature was produced on contents with the private key associated with the public key held by the object.

Parameters:
  • contents – address of contents

  • contents_size – size of contents

  • sig – address of signature

  • sig_size – size of signature

  • md_type – Digest algorithm to use (derived from the public key if md_type == MDType::None).

Returns:

Whether the signature matches the contents and the key

inline virtual bool verify(const std::vector<uint8_t> &contents, const std::vector<uint8_t> &signature)

Verify that a signature was produced on contents with the private key associated with the public key held by the object.

Parameters:
  • contents – Sequence of bytes that was signed

  • signature – Signature as a sequence of bytes

Returns:

Whether the signature matches the contents and the key

inline virtual bool verify_hash(const std::vector<uint8_t> &hash, const std::vector<uint8_t> &signature, MDType md_type)

Verify that a signature was produced on the hash of some contents with the private key associated with the public key held by the object.

Parameters:
  • hash – Hash of some content

  • signature – Signature as a sequence of bytes

  • md_type – Type of hash

Returns:

Whether the signature matches the hash and the key

virtual bool verify_hash(const uint8_t *hash, size_t hash_size, const uint8_t *sig, size_t sig_size, MDType md_type) = 0

Verify that a signature was produced on the hash of some contents with the private key associated with the public key held by the object.

Parameters:
  • hash – Hash of some content

  • hash_size – length of hash

  • sig – Signature as a sequence of bytes

  • sig_size – Length of sig

  • md_type – Digest algorithm

Returns:

Whether the signature matches the hash and the key

virtual Pem public_key_pem() const = 0

Get the public key in PEM format

virtual std::vector<uint8_t> public_key_der() const = 0

Get the public key in DER format

virtual std::vector<uint8_t> public_key_raw() const = 0

Get the raw bytes of the public key

virtual CurveID get_curve_id() const = 0

The curve ID

virtual Coordinates coordinates() const = 0

The x/y coordinates of the public key

struct Coordinates
class KeyPair

Subclassed by ccf::crypto::KeyPair_OpenSSL

class RSAPublicKey

Subclassed by ccf::crypto::RSAPublicKey_OpenSSL

Public Functions

RSAPublicKey(const Pem &pem)

Construct from PEM

RSAPublicKey(const std::vector<uint8_t> &der)

Construct from DER

RSAPublicKey(const JsonWebKeyRSAPublic &jwk)

Construct from JWK

virtual size_t key_size() const = 0

Get the key size in bits

virtual std::vector<uint8_t> rsa_oaep_wrap(const uint8_t *input, size_t input_size, const uint8_t *label = nullptr, size_t label_size = 0) = 0

Wrap data using RSA-OAEP-256 (CKM_RSA_PKCS_OAEP)

Parameters:
  • input – Pointer to raw data to wrap

  • input_size – Size of raw data

  • label – Optional string used as label during wrapping

  • label_size – Size of label

Returns:

Wrapped data

virtual std::vector<uint8_t> rsa_oaep_wrap(const std::vector<uint8_t> &input, const std::optional<std::vector<std::uint8_t>> &label = std::nullopt) = 0

Wrap data using RSA-OAEP-256 (CKM_RSA_PKCS_OAEP)

Parameters:
  • input – Raw data to wrap

  • label – Optional string used as label during wrapping

Returns:

Wrapped data

virtual Pem public_key_pem() const = 0

Get the public key in PEM format

virtual std::vector<uint8_t> public_key_der() const = 0

Get the public key in DER format

virtual JsonWebKeyRSAPublic public_key_jwk_rsa(const std::optional<std::string> &kid = std::nullopt) const = 0

Get the public key in JWK format

struct Components
class RSAKeyPair

Subclassed by ccf::crypto::RSAKeyPair_OpenSSL

Public Functions

virtual std::vector<uint8_t> rsa_oaep_unwrap(const std::vector<uint8_t> &input, const std::optional<std::vector<std::uint8_t>> &label = std::nullopt) = 0

Unwrap data using RSA-OAEP-256 (CKM_RSA_PKCS_OAEP)

Parameters:
  • input – Raw data to unwrap

  • label – Optional string used as label during unwrapping

Returns:

Unwrapped data

virtual Pem private_key_pem() const = 0

Get the private key in PEM format

virtual Pem public_key_pem() const = 0

Get the public key in PEM format

virtual std::vector<uint8_t> public_key_der() const = 0

Get the public key in DER format

enum class ccf::crypto::CurveID

Values:

enumerator NONE

No curve.

enumerator SECP384R1

The SECP384R1 curve.

enumerator SECP256R1

The SECP256R1 curve.

enumerator CURVE25519

The CURVE25519 curve.

enumerator X25519
KeyPairPtr ccf::crypto::make_key_pair(CurveID curve_id = service_identity_curve_choice)

Create a new public / private ECDSA key pair on specified curve and implementation

Parameters:

curve_id – Elliptic curve to use

Returns:

Key pair

KeyPairPtr ccf::crypto::make_key_pair(const Pem &pkey)

Create a public / private ECDSA key pair from existing private key data

Parameters:

pkey – PEM key to load

Returns:

Key pair

RSAKeyPairPtr ccf::crypto::make_rsa_key_pair(size_t public_key_size = RSAKeyPair::default_public_key_size, size_t public_exponent = RSAKeyPair::default_public_exponent)

Create a new public / private RSA key pair with specified size and exponent

Symmetric Keys

Currently, only AES-GCM is supported for symmetric encryption. New keys are generated via ccf::crypto::Entropy::random()

std::vector<uint8_t> ccf::crypto::aes_gcm_encrypt(const std::vector<uint8_t> &key, std::vector<uint8_t> &plaintext, const std::vector<uint8_t> &iv = default_iv, const std::vector<uint8_t> &aad = {})

AES-GCM Encryption with key of data

Parameters:
  • key – The key

  • plaintext – The data

  • iv – Intialization vector

  • aad – Additional authenticated data

Returns:

ciphertext

std::vector<uint8_t> ccf::crypto::aes_gcm_decrypt(const std::vector<uint8_t> &key, std::vector<uint8_t> &ciphertext, const std::vector<uint8_t> &iv = default_iv, const std::vector<uint8_t> &aad = {})

AES-GCM Decryption with key of data

Parameters:
  • key – The key

  • ciphertext – The (encrypted) data

  • iv – Initialization vector

  • aad – Additional authenticated data

Returns:

plaintext

class Entropy

Subclassed by ccf::crypto::Entropy_OpenSSL, ccf::crypto::IntelDRNG

Public Functions

virtual std::vector<uint8_t> random(size_t len) = 0

Generate len random bytes

Parameters:

len – Number of random bytes to generate

Returns:

vector random bytes

virtual void random(unsigned char *data, size_t len) = 0

Generate len random bytes into data

Parameters:
  • len – Number of random bytes to generate

  • data – Buffer to fill

virtual uint64_t random64() = 0

Generate a random uint64_t

Returns:

a random uint64_t

Signatures

Verification of signatures is supported via the Verifier class.

class Verifier

Subclassed by ccf::crypto::Verifier_OpenSSL

Public Functions

inline virtual bool verify(const uint8_t *contents, size_t contents_size, const uint8_t *sig, size_t sig_size, MDType md_type = MDType::NONE) const

Verify a signature

Parameters:
  • contents – Contents over which the signature was generated

  • contents_size – Size of contents

  • sig – Signature

  • sig_size – Size of sig

  • md_type – Hash algorithm

Returns:

Boolean indicating success

inline virtual bool verify(std::span<const uint8_t> contents, std::span<const uint8_t> sig, MDType md_type = MDType::NONE) const

Verify a signature

Parameters:
  • contents – Contents over which the signature was generated

  • sig – Signature

  • md_type – Hash algorithm

Returns:

Boolean indicating success

inline virtual bool verify(const uint8_t *contents, size_t contents_size, const uint8_t *sig, size_t sig_size, MDType md_type, HashBytes &hash_bytes) const

Verify a signature

Parameters:
  • contents – Contents over which the signature was generated

  • contents_size – Size of contents

  • sig – Signature

  • sig_size – Size of sig

  • md_type – Hash algorithm

  • hash_bytes – Output buffer for the hash

Returns:

Boolean indicating success

inline virtual bool verify(const std::vector<uint8_t> &contents, const std::vector<uint8_t> &signature, MDType md_type = MDType::NONE) const

Verify a signature

Parameters:
  • contents – Contents over which the signature was generated

  • signature – Signature

  • md_type – Hash algorithm

Returns:

Boolean indicating success

inline virtual bool verify(const std::vector<uint8_t> &contents, const std::vector<uint8_t> &signature, MDType md_type, HashBytes &hash_bytes) const

Verify a signature

Parameters:
  • contents – Contents over which the signature was generated

  • signature – Signature

  • md_type – Hash algorithm

  • hash_bytes – Output buffer for the hash

Returns:

Boolean indicating success

inline virtual bool verify_hash(const uint8_t *hash, size_t hash_size, const uint8_t *sig, size_t sig_size, MDType md_type = MDType::NONE)

Verify a signature over a hash

Parameters:
  • hash – Hash over which the signature was generated

  • hash_size – Size of hash

  • sig – Signature

  • sig_size – Size of sig

  • md_type – Hash algorithm

Returns:

Boolean indicating success

inline virtual bool verify_hash(const std::vector<uint8_t> &hash, const std::vector<uint8_t> &signature, MDType md_type = MDType::NONE)

Verify a signature over a hash

Parameters:
  • hash – Hash over which the signature was generated

  • signature – Signature

  • md_type – Hash algorithm

Returns:

Boolean indicating success

template<size_t SIZE>
inline bool verify_hash(const std::array<uint8_t, SIZE> &hash, const std::vector<uint8_t> &signature, MDType md_type = MDType::NONE)

Verify a signature over a hash

Parameters:
  • hash – Hash over which the signature was generated

  • signature – Signature

  • md_type – Hash algorithm

Returns:

Boolean indicating success

inline virtual Pem public_key_pem() const

Extract the public key of the certificate in PEM format

Returns:

PEM encoded public key

inline virtual std::vector<uint8_t> public_key_der() const

Extract the public key of the certificate in DER format

Returns:

DER encoded public key

virtual bool verify_certificate(const std::vector<const Pem*> &trusted_certs, const std::vector<const Pem*> &chain = {}, bool ignore_time = false) = 0

Verify the certificate (held internally)

Parameters:
  • trusted_certs – Vector of trusted certificates

  • chain – Vector of ordered untrusted certificates used to build a chain to trusted certificates

  • ignore_time – Flag to disable certificate expiry checks

Returns:

true if the verification is successful

virtual bool is_self_signed() const = 0

Indicates whether the certificate (held intenally) is self-signed

virtual std::string serial_number() const = 0

The serial number of the certificate

virtual std::pair<std::string, std::string> validity_period() const = 0

The validity period of the certificate

virtual size_t remaining_seconds(const std::chrono::system_clock::time_point &now) const = 0

The number of seconds of the validity period of the certificate remaining

virtual double remaining_percentage(const std::chrono::system_clock::time_point &now) const = 0

The percentage of the validity period of the certificate remaining

virtual std::string subject() const = 0

The subject name of the certificate

Key Wrapping

PKCS11 2.1.8 CKM_RSA_PKCS_OAEP

std::vector<uint8_t> ccf::crypto::ckm_rsa_pkcs_oaep_wrap(RSAPublicKeyPtr wrapping_key, const std::vector<uint8_t> &unwrapped, const std::optional<std::vector<uint8_t>> &label = {})

PKCS11 2.1.8 CKM_RSA_PKCS_OAEP wrap

Parameters:
  • wrapping_key – The wrapping (encryption) key

  • unwrapped – The unwrapped key to be wrapped

  • label – Optional label

Returns:

Wrapped key

std::vector<uint8_t> ccf::crypto::ckm_rsa_pkcs_oaep_wrap(const Pem &wrapping_key, const std::vector<uint8_t> &unwrapped, const std::optional<std::vector<uint8_t>> &label = {})

PKCS11 2.1.8 CKM_RSA_PKCS_OAEP

Parameters:
  • wrapping_key – The wrapping (encryption) key

  • unwrapped – The unwrapped key to be wrapped

  • label – Optional label

Returns:

Wrapped key

std::vector<uint8_t> ccf::crypto::ckm_rsa_pkcs_oaep_unwrap(RSAKeyPairPtr wrapping_key, const std::vector<uint8_t> &wrapped, const std::optional<std::vector<uint8_t>> &label = {})

PKCS11 2.1.8 CKM_RSA_PKCS_OAEP unwrap

Parameters:
  • wrapping_key – The wrapping (encryption) key

  • wrapped – The wrapped key to unwrap

  • label – Optional label

Returns:

Unwrapped key

std::vector<uint8_t> ccf::crypto::ckm_rsa_pkcs_oaep_unwrap(const Pem &wrapping_key, const std::vector<uint8_t> &wrapped, const std::optional<std::vector<uint8_t>> &label = {})

PKCS11 2.1.8 CKM_RSA_PKCS_OAEP

Parameters:
  • wrapping_key – The wrapping (encryption) key

  • wrapped – The wrapped key to unwrap

  • label – Optional label

Returns:

Unwrapped key

PKCS11 2.14.3 CKM_AES_KEY_WRAP_PAD (RFC 5649)

std::vector<uint8_t> ccf::crypto::ckm_aes_key_wrap_pad(const std::vector<uint8_t> &wrapping_key, const std::vector<uint8_t> &unwrapped)

PKCS11 2.14.3 CKM_AES_KEY_WRAP_PAD wrap

Parameters:
  • wrapping_key – The wrapping (encryption) key

  • unwrapped – The unwrapped key to be wrapped

Returns:

Wrapped key

std::vector<uint8_t> ccf::crypto::ckm_aes_key_unwrap_pad(const std::vector<uint8_t> &wrapping_key, const std::vector<uint8_t> &wrapped)

PKCS11 2.14.3 CKM_AES_KEY_WRAP_PAD unwrap

Parameters:
  • wrapping_key – The wrapping (encryption) key

  • wrapped – The wrapped key to unwrap

Returns:

Unwrapped key

PKCS11 2.1.21 CKM_RSA_AES_KEY_WRAP

std::vector<uint8_t> ccf::crypto::ckm_rsa_aes_key_wrap(size_t aes_key_size, RSAPublicKeyPtr wrapping_key, const std::vector<uint8_t> &unwrapped, const std::optional<std::vector<uint8_t>> &label = {})

PKCS11 2.1.21 CKM_RSA_AES_KEY_WRAP wrap

Parameters:
  • aes_key_size – Key size 128, 192 or 256.

  • wrapping_key – The wrapping (encryption) key

  • unwrapped – The key to wrap

  • label – Optional label

Returns:

Wrapped key

std::vector<uint8_t> ccf::crypto::ckm_rsa_aes_key_wrap(size_t aes_key_size, const Pem &wrapping_key, const std::vector<uint8_t> &unwrapped, const std::optional<std::vector<uint8_t>> &label = {})

PKCS11 2.1.21 CKM_RSA_AES_KEY_WRAP wrap

Parameters:
  • aes_key_size – Key size 128, 192 or 256.

  • wrapping_key – The wrapping (encryption) key

  • unwrapped – The key to wrap

  • label – Optional label

Returns:

Wrapped key

std::vector<uint8_t> ccf::crypto::ckm_rsa_aes_key_unwrap(RSAKeyPairPtr wrapping_key, const std::vector<uint8_t> &wrapped, const std::optional<std::vector<uint8_t>> &label = {})

PKCS11 2.1.21 CKM_RSA_AES_KEY_WRAP unwrap

Parameters:
  • wrapping_key – The wrapping (encryption) key

  • wrapped – The wrapped key to unwrap

  • label – Optional label

Returns:

Unwrapped key

std::vector<uint8_t> ccf::crypto::ckm_rsa_aes_key_unwrap(const Pem &wrapping_key, const std::vector<uint8_t> &wrapped, const std::optional<std::vector<uint8_t>> &label = {})

PKCS11 2.1.21 CKM_RSA_AES_KEY_WRAP unwrap

Parameters:
  • wrapping_key – The wrapping (encryption) key

  • wrapped – The wrapped key to unwrap

  • label – Optional label

Returns:

Unwrapped key