secapi-sys 0.3.0

FFI bindings to SecAPI
/*
 * Copyright 2020-2023 Comcast Cable Communications Management, LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @file sa_key.h
 *
 * This file contains the function declarations for the "key" module of the SecAPI. "key"
 * module functions perform operations related to importing, generating, deriving, and negotiating
 * new keys.
 */

#ifndef SA_KEY_H
#define SA_KEY_H

#include "sa_types.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * Generate a key.
 *
 * @param[out] key Generated key.
 * @param[in] rights Key rights for the newly created key.
 * @param[in] key_type Type of key to create.
 * @param[in] parameters Key type specific parameters for key generation. Use
 * sa_generate_parameters_symmetric with SA_KEY_TYPE_SYMMETRIC, sa_generate_parameters_rsa with
 * SA_KEY_TYPE_RSA, sa_generate_parameters_ec with SA_KEY_TYPE_EC, sa_generate_parameters_dh with
 * SA_KEY_TYPE_DH.
 * @return Operation status. Possible values are:
 * + SA_STATUS_OK - Operation succeeded.
 * + SA_STATUS_NO_AVAILABLE_RESOURCE_SLOT - There are no available key slots.
 * + SA_STATUS_NULL_PARAMETER - key, rights, or parameters (if required) is NULL.
 * + SA_STATUS_INVALID_PARAMETER
 *   + Invalid key type specified.
 *   + Invalid type specific parameter value encountered.
 * + SA_STATUS_OPERATION_NOT_SUPPORTED - Implementation does not support the specified operation.
 * + SA_STATUS_SELF_TEST - Implementation self-test has failed.
 * + SA_STATUS_INTERNAL_ERROR - An unexpected error has occurred.
 */
sa_status sa_key_generate(
        sa_key* key,
        const sa_rights* rights,
        sa_key_type key_type,
        void* parameters);

/**
 * Export (rewrap) the key for persistence. Key rights are cryptographically bound to the key
 * material. Key material is encrypted using a device unique rewrap key. The exported key has an
 * integrity envelope that will be checked on key import. Encryption and integrity keys used to
 * protect the exported key container are derived from device root key using a 3-stage key ladder
 * that is not exposed to the users of the SecAPI.
 *
 * @param[out] out Output buffer. If NULL, size required to export key is returned.
 * @param[in,out] out_length Size of output buffer in bytes. Set to number of bytes written on
 * function return.
 * @param[in] mixin Input for the 3rd derivation stage of encryption and mac key used to protect the
 * exported key container. Defaults to all zeros if NULL.
 * @param[in] mixin_length Mixin length in bytes. Has to be equal to 16.
 * @param[in] key Key to export.
 * @return Operation status. Possible values are:
 * + SA_STATUS_OK - Operation succeeded.
 * + SA_STATUS_NULL_PARAMETER - out_length or key is NULL.
 * + SA_STATUS_INVALID_PARAMETER
 *   + out is not NULL and *out_length is smaller than required for exported key container.
 *   + mixin is not NULL and mixin_length is not 16.
 * + SA_STATUS_OPERATION_NOT_ALLOWED - Key usage requirements are not met for the specified
 * operation.
 * + SA_STATUS_OPERATION_NOT_SUPPORTED - Implementation does not support the specified operation.
 * + SA_STATUS_SELF_TEST - Implementation self-test has failed.
 * + SA_STATUS_INTERNAL_ERROR - An unexpected error has occurred.
 */
sa_status sa_key_export(
        void* out,
        size_t* out_length,
        const void* mixin,
        size_t mixin_length,
        sa_key key);

/**
 * Provision a key.
 * This function is proposed to support the provisioning of keys from an operator's key
 * provisioning service to a specific TA.
 * #1.	Field provisioning service delivers the encrypted TA Key to the device.
 * #2.	The TA Key is imported and provisioned to SecAPI3 using new API: sa_key_provision_ta().
 * #3.	SecAPI3 TA decrypts TA Key and converts key to SOC vendor TA Key format.
 * #4.	SecAPI3 TA calls the SOC vendor-specific API to deliver the key to the TA.
 * #5.	The key will be loaded for use within the TA. If the key received by the TA is new or updated
        and the TA supports secure storage, it will store the key to TA Secure Storage.
 * #6.	This provisioning flow (Steps 2-5) will occur upon every device reboot/initialization. SOC
        Vendor TA Key updates will only be written to TAs supporting secure store upon receiving a new
        or updated key. The TA Key is not imported/stored in SecAPI3 when the sa_key_provision_ta() API
        is used.
 *
 * @param[in] ta_key_type (enum) specifies the type of key being provisioned to the TA as defined in
   [TA Key Type Definition](#ta-key-type-definition).
 * @param[in] in (void pointer) pointer to the input key and credential data.
 * @param[in] in_length (integer) size of the data buffer pointed to by in bytes.
 * @param[in] parameters (pointer) format specific parameters for the protection key used by the key
   provisioning service.

 * The sa_key_provision_ta API will return one of the following status conditions:
 * + SA_STATUS_OK - Operation succeeded.
 * + SA_STATUS_INVALID_KEY_FORMAT - Input data failed the format validation.
 * + SA_STATUS_NULL_PARAMETER - ta_key_type, in, in_length, or the key provisioning object
 *   parameters are NULL.
 * + SA_STATUS_INVALID_PARAMETER
 *   - Invalid key format.
 *   - Invalid format value.
 *   - Invalid format specific parameter value encountered.
 * + SA_STATUS_OPERATION_NOT_SUPPORTED - Implementation does not support the specified operation.
 * + SA_STATUS_VERIFICATION_FAILED - Signature verification has failed.
 * + SA_STATUS_NO_AVAILABLE_RESOURCE_SLOT - There are no available key slots.
 * + SA_STATUS_INTERNAL_ERROR - An unexpected error has occurred.
 */

sa_status sa_key_provision_ta (
        sa_key_type_ta ta_key_type,
        const void* in,
        size_t in_length,
        void* parameters);

/**
 * Import a key.
 * + Symmetric keys are raw bytes in big-endian byte order.
 * + Asymmetric Private Keys must be in the OneAsymmetricKey format as defined in RFC 5958 (this obsoletes the PKCS 8
 * format defined in RFC 5208).
 *
 * @param[out] key Imported key handle.
 * @param[in] key_format Key format.
 * @param[in] in Input data.
 * @param[in] in_length Size of input data in bytes.
 * @param[in] parameters Format specific import parameters. Use sa_import_parameters_symmetric with
 * SA_KEY_FORMAT_SYMMETRIC_BYTES, sa_import_parameters_ec_private_bytes with SA_KEY_FORMAT_EC_PRIVATE_BYTES,
 * sa_import_parameters_rsa_private_key_info with SA_KEY_FORMAT_RSA_PRIVATE_KEY_INFO, sa_import_parameters_soc with
 * SA_KEY_FORMAT_SOC (although this parameter can be NULL for backward compatibility, it is now required for all
 * new applications), sa_import_parameters_typej with SA_KEY_FORMAT_TYPEJ.
 * @return Operation status. Possible values are:
 * + SA_STATUS_OK - Operation succeeded.
 * + SA_STATUS_NO_AVAILABLE_RESOURCE_SLOT - There are no available key slots.
 * + SA_STATUS_INVALID_KEY_FORMAT - Input data failed the format validation.
 * + SA_STATUS_NULL_PARAMETER - key, in, or parameters (if required) is NULL.
 * + SA_STATUS_INVALID_PARAMETER
 *   + Invalid format value.
 *   + Invalid format specific parameter value encountered.
 * + SA_STATUS_OPERATION_NOT_SUPPORTED - Implementation does not support the specified operation.
 * + SA_STATUS_SELF_TEST - Implementation self-test has failed.
 * + SA_STATUS_VERIFICATION_FAILED - Signature verification has failed.
 * + SA_STATUS_INTERNAL_ERROR - An unexpected error has occurred.
 */
sa_status sa_key_import(
        sa_key* key,
        sa_key_format key_format,
        const void* in,
        size_t in_length,
        void* parameters);

/**
 * Unwrap the key.
 * + Unwrapped Symmetric keys are raw bytes in big-endian byte order.
 * + Unwrapped Asymmetric Private Keys must be in the OneAsymmetricKey format as defined in RFC 5958 (this obsoletes the
 * PKCS 8 format defined in RFC 5208).
 *
 * @param[out] key Unwrapped key handle.
 * @param[in] rights Key rights to associate with the unwrapped key.
 * @param[in] key_type Type of the wrapped key.
 * @param[in] type_parameters Additional key type specific parameters. Use
 * sa_unwrap_type_parameters_ec with SA_KEY_TYPE_EC.
 * @param[in] cipher_algorithm Wrapping algorithm.
 * @param[in] algorithm_parameters Additional algorithm specific parameters. Use
 * sa_unwrap_parameters_aes_cbc with SA_CIPHER_ALGORITHM_AES_CBC and
 * SA_CIPHER_ALGORITHM_AES_CBC_PKCS7, sa_unwrap_parameters_aes_ctr with SA_CIPHER_ALGORITHM_AES_CTR,
 * sa_unwrap_parameters_aes_gcm with SA_CIPHER_ALGORITHM_AES_GCM, sa_unwrap_parameters_chacha20 with
 * SA_CIPHER_ALGORITHM_CHACHA20, sa_unwrap_parameters_chacha20_poly1305 with SA_CIPHER_ALGORITHM_CHACHA20,
 * sa_unwrap_parameters_rsa_oaep with SA_CIPHER_ALGORITHM_RSA_OAEP, sa_unwrap_parameters_ec_elgamal
 * with SA_CIPHER_ALGORITHM_EC_ELGAMAL.
 * @param[in] wrapping_key Wrapping key.
 * @param[in] in Wrapped key ciphertext.
 * @param[in] in_length Wrapped key ciphertext length.
 * @return Operation status. Possible values are:
 * + SA_STATUS_OK - Operation succeeded.
 * + SA_STATUS_NO_AVAILABLE_RESOURCE_SLOT - There are no available key slots.
 * + SA_STATUS_INVALID_KEY_FORMAT - Input data failed the format validation.
 * + SA_STATUS_INVALID_KEY_TYPE - Wrapping key type is not valid for the specified algorithm.
 * + SA_STATUS_NULL_PARAMETER - key, rights, type_parameters (if required), algorithm_parameters (if
 * required), wrapping_key, or in is NULL.
 * + SA_STATUS_INVALID_PARAMETER
 *   + in_length is not valid for specified algorithm.
 *   + Invalid type value.
 *   + Invalid type specific parameter encountered.
 *   + Invalid algorithm.
 *   + Invalid algorithm specific parameter value encountered.
 * + SA_STATUS_OPERATION_NOT_ALLOWED - Wrapping key usage requirements are not met for the specified
 * operation.
 * + SA_STATUS_OPERATION_NOT_SUPPORTED - Implementation does not support the specified operation.
 * + SA_STATUS_SELF_TEST - Implementation self-test has failed.
 * + SA_STATUS_VERIFICATION_FAILED
 *   + Invalid padding value has been encountered.
 *   + Tag verification has failed.
 * + SA_STATUS_INTERNAL_ERROR - An unexpected error has occurred.
 */
sa_status sa_key_unwrap(
        sa_key* key,
        const sa_rights* rights,
        sa_key_type key_type,
        void* type_parameters,
        sa_cipher_algorithm cipher_algorithm,
        void* algorithm_parameters,
        sa_key wrapping_key,
        const void* in,
        size_t in_length);

/**
 * Obtain the public component of an asymmetric key.
 * + Public keys are in the SubjectPublicKeyInfo format described in RFC 5280
 * + Additional RSA public key info is defined in RFC 3279
 * + Additional EC public key info is defined in RFC 5480
 * + Additional ED25519, X25519, ED448, and X448 public keys info is defined in RFC 8410.
 * + Additional DH public key info is defined in RFC 3279
 *
 * @param[out] out Output buffer. If NULL, size required for public key is returned.
 * @param[in,out] out_length Size of the output buffer in bytes. Set to public key length on
 * function exit.
 * @param[in] key Private key handle.
 * @return Operation status. Possible values are:
 * + SA_STATUS_OK - Operation succeeded.
 * + SA_STATUS_INVALID_KEY_TYPE - Key type is not valid for the specified operation.
 * + SA_STATUS_NULL_PARAMETER - out_length or key is NULL.
 * + SA_STATUS_INVALID_PARAMETER - out is not NULL and *out_length is too small to store the public key.
 * + SA_STATUS_OPERATION_NOT_SUPPORTED - Implementation does not support the specified operation.
 * + SA_STATUS_SELF_TEST - Implementation self-test has failed.
 * + SA_STATUS_INTERNAL_ERROR - An unexpected error has occurred.
 */
sa_status sa_key_get_public(
        void* out,
        size_t* out_length,
        sa_key key);

/**
 * Derive a symmetric key using the specified KDF.
 *
 * @param[out] key Derived key.
 * @param[in] rights Key rights to associate with the derived key.
 * @param[in] kdf_algorithm KDF algorithm.
 * @param[in] parameters Algorithm specific parameters. Use sa_kdf_parameters_root_key_ladder with
 * SA_KDF_ALGORITHM_ROOT_KEY_LADDER or SA_KDF_ALGORITHM_COMMON_ROOT_KEY_LADDER,
 * sa_kdf_parameters_hkdf with SA_KDF_ALGORITHM_HKDF,
 * sa_kdf_parameters_concat with SA_KDF_ALGORITHM_CONCAT,
 * sa_kdf_parameters_ansi_x963 with SA_KDF_ALGORITHM_ANSI_X963,
 * sa_kdf_parameters_cmac with SA_KDF_ALGORITHM_CMAC,
 * sa_kdf_parameters_netflix with SA_KDF_ALGORITHM_NETFLIX.
 * @return Operation status. Possible values are:
 * + SA_STATUS_OK - Operation succeeded.
 * + SA_STATUS_NO_AVAILABLE_RESOURCE_SLOT - There are no available key slots.
 * + SA_STATUS_INVALID_KEY_TYPE - Key type is not valid for the specified operation.
 * + SA_STATUS_NULL_PARAMETER - key, rights, or parameters is NULL.
 * + SA_STATUS_INVALID_PARAMETER
 *   + Invalid algorithm value.
 *   + Invalid algorithm specific parameter value encountered.
 * + SA_STATUS_OPERATION_NOT_ALLOWED - Key usage requirements are not met for the specified
 * operation.
 * + SA_STATUS_OPERATION_NOT_SUPPORTED - Implementation does not support the specified operation.
 * + SA_STATUS_SELF_TEST - Implementation self-test has failed.
 * + SA_STATUS_INTERNAL_ERROR - An unexpected error has occurred.
 */
sa_status sa_key_derive(
        sa_key* key,
        const sa_rights* rights,
        sa_kdf_algorithm kdf_algorithm,
        void* parameters);

/**
 * Compute a shared secret using specified key exchange algorithm.
 *
 * @param[out] key Shared secret key.
 * @param[in] rights Key rights to associate with the shared secret key.
 * @param[in] key_exchange_algorithm Key exchange algorithm.
 * @param[in] private_key Private key.
 * @param[in] other_public Public component of other party in network order.
 * @param[in] other_public_length Length of the public component of the other party in bytes.
 * @param[in] parameters Additional algorithm specific parameters. Use
 * sa_key_exchange_parameters_netflix_authenticated_dh with
 * SA_KEY_EXCHANGE_ALGORITHM_NETFLIX_AUTHENTICATED_DH.
 * @return Operation status. Possible values are:
 * + SA_STATUS_OK - Operation succeeded.
 * + SA_STATUS_NO_AVAILABLE_RESOURCE_SLOT - There are no available key slots.
 * + SA_STATUS_INVALID_KEY_TYPE - Private key type is not valid for the specified operation.
 * + SA_STATUS_NULL_PARAMETER - key, rights, private_key, other_public, or parameters is NULL.
 * + SA_STATUS_INVALID_PARAMETER
 *   + Invalid algorithm value.
 *   + Invalid algorithm specific parameter value encountered.
 *   + other_public_length is not valid for specified algorithm and key.
 * + SA_STATUS_OPERATION_NOT_ALLOWED - Private key usage requirements are not met for the specified
 * operation.
 * + SA_STATUS_OPERATION_NOT_SUPPORTED - Implementation does not support the specified operation.
 * + SA_STATUS_SELF_TEST - Implementation self-test has failed.
 * + SA_STATUS_INTERNAL_ERROR - An unexpected error has occurred.
 */
sa_status sa_key_exchange(
        sa_key* key,
        const sa_rights* rights,
        sa_key_exchange_algorithm key_exchange_algorithm,
        sa_key private_key,
        const void* other_public,
        size_t other_public_length,
        void* parameters);

/**
 * Release a key. Any existing cipher, MAC, or SVP contexts can still be used until they are
 * released.
 *
 * @param[in] key Key to release
 * @return Operation status. Possible values are:
 * + SA_STATUS_OK - Operation succeeded.
 * + SA_STATUS_INVALID_PARAMETER - key handle is invalid.
 * + SA_STATUS_OPERATION_NOT_SUPPORTED - Implementation does not support the specified operation.
 * + SA_STATUS_SELF_TEST - Implementation self-test has failed.
 * + SA_STATUS_INTERNAL_ERROR - An unexpected error has occurred.
 */
sa_status sa_key_release(sa_key key);

/**
 * Obtain the key header.
 *
 * @param[out] header Key header.
 * @param[in] key Key handle.
 * + SA_STATUS_OK - Operation succeeded.
 * + SA_STATUS_NULL_PARAMETER - header is null.
 * + SA_STATUS_INVALID_PARAMETER - key handle is invalid.
 * + SA_STATUS_OPERATION_NOT_SUPPORTED - Implementation does not support the specified operation.
 * + SA_STATUS_SELF_TEST - Implementation self-test has failed.
 * + SA_STATUS_INTERNAL_ERROR - An unexpected error has occurred.
 */
sa_status sa_key_header(
        sa_header* header,
        sa_key key);

/**
 * Returns the digest of a key using the specified digest algorithm. Symmetric and EC keys will be digested in their raw
 * format. RSA keys will be digested in their PKCS8 format. Digesting a DH key is invalid.
 *
 * @param[out] out Output buffer. Can be set to NULL to obtain the required length.
 * @param[in,out] out_length Output buffer length in bytes.
 * @param[in] key the key to digest.
 * @param[in] digest_algorithm the digest algorithm to use.
 * @return Operation status. Possible values are:
 * + SA_STATUS_OK - Operation succeeded.
 * + SA_STATUS_NULL_PARAMETER - out_length or context is NULL.
 * + SA_STATUS_INVALID_PARAMETER
 *   + out is not NULL and *out_length value is too small to hold the result.
 *   + key is a DH key
 * + SA_STATUS_OPERATION_NOT_SUPPORTED - Implementation does not support the specified operation.
 * + SA_STATUS_SELF_TEST - Implementation self-test has failed.
 * + SA_STATUS_INTERNAL_ERROR - An unexpected error has occurred.
 */
sa_status sa_key_digest(
        void* out,
        size_t* out_length,
        sa_key key,
        sa_digest_algorithm digest_algorithm);

#ifdef __cplusplus
}
#endif

#endif /* SA_KEY_H */