adding security misc from Vx7 to 6.9 (original files from vx7) (#5)

Co-authored-by: neelimap <neelimaps@neominds.in>
Reviewed-on: http://13.234.246.121:3000/Neominds/ossl35vx69/pulls/5
Reviewed-by: Siddhant Singh <siddhant.singh@neominds.in>
Co-authored-by: Neelima P S <neelima.ps@neominds.in>
Co-committed-by: Neelima P S <neelima.ps@neominds.in>
This commit is contained in:
2026-07-30 18:09:00 +05:30
committed by neelimap
co-authored by neelimap
parent 368226261b
commit 122392cfc0
60 changed files with 9586 additions and 0 deletions
+42
View File
@@ -0,0 +1,42 @@
/* banned.h - header file listing banned APIs in VxWorks */
/*
* Copyright (c) 2019-2021 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
#ifndef __INCbannedh
#define __INCbannedh
/* includes */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define _WRS_BANNED_TEXT(bannedFunc, recommendedFunc) \
(bannedFunc " is now banned, consider using " recommendedFunc " instead")
#ifdef __clang__
#define _WRS_BANNED_MSG(msg) __attribute__((diagnose_if(1, msg, "error")));
#else
#define _WRS_BANNED_MSG(msg) __attribute__((error(msg)))
#endif
#define _WRS_BANNED(bannedFunc, recommendedFunc) \
_WRS_BANNED_MSG(_WRS_BANNED_TEXT(bannedFunc, recommendedFunc))
char * strcpy (char * a, const char * b) _WRS_BANNED("strcpy", "strncpy_s");
char * strcat (char * a, const char * b) _WRS_BANNED("strcat", "strncat_s");
char * mktemp (char *tmplate) _WRS_BANNED("mktemp", "mkstemp or mkdtemp");
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __INCbannedh */
@@ -0,0 +1,445 @@
/* ipcom_key_db.h - Public API of IPCOM key database */
/*
* Copyright (c) 2006-2014, 2018, 2020-2021 Wind River Systems, Inc.
*
* The right to copy, distribute, modify or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
#ifndef IPCOM_KEY_DB_H
#define IPCOM_KEY_DB_H
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
DESCRIPTION
This library contains the API for the IPCOM key database.
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
#include <vsbConfig.h>
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#include <ipcom_type.h>
#include <ipcom_cstyle.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
#define IPCOM_USE_KEY_DB
#define IPCOM_USE_KEY_DB_CMD
#define IPCOM_USE_KEY_DB_CMD_VERIFY
#define IPCRYPTO
/* Note: Changing IPCOM_KEY_DB_MAX_BUF will affect stack usage. */
#ifndef IPCOM_KEY_DB_MAX_BUF
#define IPCOM_KEY_DB_MAX_BUF 128
#endif
#ifndef IPCOM_KEY_DB_MAX_ID
#define IPCOM_KEY_DB_MAX_ID 32
#endif
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/* Forward declarations */
struct evp_pkey_st;
struct x509_st;
/*
****************************************************************************
* 6 FUNCTIONS
****************************************************************************
*/
/*******************************************************************************
*
* ipcom_key_db_pkey_get - get key with specified key_id
*
* This routine returns the public key with the specified key ID
*
* Parameter:
* \is
* \i <key_id>
* The key ID of the key to get
* \ie
*
* RETURNS: A pointer to a public key or NULL if the key does not exist.
*
* ERRNO:
*/
IP_PUBLIC struct evp_pkey_st* ipcom_key_db_pkey_get
(
const char* key_id
);
/*******************************************************************************
*
* ipcom_key_db_pkey_get2 - get key matching an X509 certificate
*
* This routine searches the key database for a public key pair matching the
* the public key in the specified X509 certificate.
*
* Parameter:
* \is
* \i <x509>
* holds the X509 certificate whose private key should be returned
* \i <key_id> pointer to buffer to put the key id in.
* \i <key_id_len> length of the key_id buffer.
* \ie
*
* RETURNS: A pointer to a public key or NULL if no matching key could be found.
*
* ERRNO:
*/
IP_PUBLIC struct evp_pkey_st* ipcom_key_db_pkey_get2
(
struct x509_st* x509,
char* key_id,
int* key_id_len
);
/*******************************************************************************
*
* ipcom_key_db_pkey_import - store a public key pair in the key database
*
* This routine imports a public key pair into the key key database.
*
* Parameter:
* \is
* \i <key_id>
* key id of the key being imported
* \i <key>
* the actual key to import
* \ie
*
* RETURNS: IPCOM_SUCCESS if successful, IPCOM_ERR_INVALID_ARG if an invalid key
* is given as argument, IPCOM_ERR_ALREADY_INSTALLED if key with the same key ID
* is already stored in the key database.
*
* ERRNO:
*/
IP_PUBLIC Ip_err ipcom_key_db_pkey_import
(
const char* key_id,
struct evp_pkey_st* key
);
/*******************************************************************************
*
* ipcom_key_db_pkey_del - delete public key pair
*
* Delete public key pair with ID key_id from the key db.
*
* Parameter:
* \is
* \i <key_id>
* key ID of the key to delete
* \ie
*
* RETURNS:
* IPCOM_SUCCESS if the key was deleted
* IPCOM_ERR_NOT_FOUND if key ID does not exist
* IPCOM_ERR_FAILED for general errors
*
* ERRNO:
*/
IP_PUBLIC Ip_err ipcom_key_db_pkey_del
(
const char* key_id
);
/*******************************************************************************
*
* ipcom_key_db_pkey_opendb - open the database for reading
*
* This routine returns a handle that can be used to iterate all key IDs in the
* database. Note that public keys and buffers/pre-shared keys have different
* name spaces.
*
* RETURNS: A handle to be used in subsequent calls to ipcom_key_db_pkey_readdb
* and ipcom_key_db_pkey_closedb.
*
* ERRNO:
*/
IP_PUBLIC void* ipcom_key_db_pkey_opendb
(
void
);
/*******************************************************************************
*
* ipcom_key_db_pkey_readdb - return next key ID from the database
*
* This routine returns the next key ID from the database.
*
* Parameter:
* \is
* \i <handle>
* handle returned from ipcom_key_db_pkey_opendb
* \i <name>
* buffer to store the key ID in
* \i <name>
* length of name buffer
* \ie
*
* RETURNS:
* IPCOM_SUCCESS if successful
* IPCOM_ERR_END if no more entries can be read
* IPCOM_ERR_FAILED in case of error
*
* ERRNO:
*/
IP_PUBLIC Ip_err ipcom_key_db_pkey_readdb
(
void* handle,
char* name,
int name_len
);
/*******************************************************************************
*
* ipcom_key_db_pkey_closedb - close handle
*
* This routine closes a handle used to iterate all key IDs in the
* database.
*
* Parameter:
* \is
* \i <handle>
* handle returned from ipcom_key_db_pkey_opendb
* \ie
*
* RETURNS: A handle to be used in subsequent calls to ipcom_key_db_pkey_readdb
* and ipcom_key_db_pkey_closedb.
*
* ERRNO:
*/
IP_PUBLIC Ip_err ipcom_key_db_pkey_closedb
(
void* handle
);
/*******************************************************************************
*
* ipcom_key_db_buf_import - import buffer into the key db and give it ID key_id
*
* Import buffer into the key db and give it ID key_id. The buffer is typically a
* password or a pre-shared key.
*
* Parameter:
* \is
* \i <key_id>
* key ID of the key to import
* \i <key>
* the key/buffer to import
* \i <key_len>
* length of the key
* \ie
*
* RETURNS:
* IPCOM_SUCCESS if the key was successfully imported
* IPCOM_ERR_INVALID_ARG if the key is too long
* IPCOM_ERR_ALREADY_INSTALLED if the key ID already exists
* IPCOM_ERR_FAILED for general errors
*
* ERRNO:
*/
IP_PUBLIC Ip_err ipcom_key_db_buf_import
(
const char* key_id,
const UINT8* key,
int key_len
);
/*******************************************************************************
*
* ipcom_key_db_buf_get - get key
*
* Get buffer with specified key_id
*
* Parameter:
* \is
* \i <key_id>
* key ID of the key to fetch
* \i <key>
* pointer to the buffer to store the key in
* \i <key_len>
* length of the key buffer
* \ie
*
* RETURNS:
* IPCOM_SUCCESS if the key was succesfully retrieved
* IPCOM_ERR_NOT_FOUND if the key ID does not exist
* IPCOM_ERR_NO_MEMORY if not enough memory is available to complete the request
* IPCOM_ERR_FAILED for general errors
*
* ERRNO:
*/
IP_PUBLIC Ip_err ipcom_key_db_buf_get
(
const char* key_id,
UINT8* key,
int* key_len
);
/*******************************************************************************
*
* ipcom_key_db_buf_del - delete buffer from key database
*
* Delete buffer with ID key_id from the key db
*
* Parameter:
* \is
* \i <key_id>
* Key ID of key to delete
* \ie
*
* RETURNS:
* IPCOM_SUCCESS if the key was deleted
* IPCOM_ERR_NOT_FOUND if key ID does not exist
* IPCOM_ERR_FAILED for general errors
*
* ERRNO:
*/
IP_PUBLIC Ip_err ipcom_key_db_buf_del
(
const char* key_id
);
/*******************************************************************************
*
* ipcom_key_db_buf_opendb - open the database for reading
*
* This routine returns a handle that can be used to iterate all key IDs in the
* database. Note that public keys and buffers/pre-shared keys have different
* name spaces.
*
* RETURNS: A handle to be used in subsequent calls to ipcom_key_db_buf_readdb
* and ipcom_key_db_buf_closedb.
* NULL in case of error.
*
* ERRNO:
*/
IP_PUBLIC void* ipcom_key_db_buf_opendb
(
void
);
/*******************************************************************************
*
* ipcom_key_db_buf_readdb - return next key ID from the database
*
* This routine returns the next key ID from the database.
*
* Parameter:
* \is
* \i <handle>
* handle returned from ipcom_key_db_pkey_opendb
* \i <name>
* buffer to store the key ID in
* \i <name>
* length of name buffer
* \ie
*
* RETURNS:
* IPCOM_SUCCESS if successful
* IPCOM_ERR_END if no more entries can be read
* IPCOM_ERR_FAILED in case of error
*
* ERRNO:
*/
IP_PUBLIC Ip_err ipcom_key_db_buf_readdb
(
void* handle,
char* name,
int name_len
);
/*******************************************************************************
*
* ipcom_key_db_buf_closedb - close handle
*
* This routine closes a handle used to iterate all key IDs in the
* database.
*
* Parameter:
* \is
* \i <handle>
* handle returned from ipcom_key_db_buf_opendb
* \ie
*
* RETURNS:
* IPCOM_SUCCESS if the handle was closed
* IPCOM_ERR_FAILED if the handle could not be closed;
*
* ERRNO:
*/
IP_PUBLIC Ip_err ipcom_key_db_buf_closedb
(
void* handle
);
/*******************************************************************************
*
* ipcom_key_db_file_ready - wait for the vault storage device ready
*
* This routine delay check the vault storage device ready
*
* RETURNS: void
*
* ERRNO:
*/
IP_GLOBAL void ipcom_key_db_file_ready
(
void
);
#ifdef __cplusplus
}
#endif
#endif
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
@@ -0,0 +1,311 @@
/** @file
Platform Key, Key Exchange Key, and Image signature database are defined
for the signed image validation.
Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
@par Revision Reference:
GUIDs defined in UEFI 2.3.1 spec.
**/
/*
* Copyright (c) 2017 Wind River Systems, Inc.
*
* The right to copy, distribute, modify or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River License agreement.
*/
/*
modification history
--------------------
18sep17,lta written (F8920)
*/
#ifndef __IMAGE_AUTHTICATION_H__
#define __IMAGE_AUTHTICATION_H__
#ifdef notused
#include <Guid/GlobalVariable.h>
#endif
#define EFI_IMAGE_SECURITY_DATABASE_GUID \
{ \
0xd719b2cb, 0x3d3a, 0x4596, { 0xa3, 0xbc, 0xda, 0xd0, 0xe, 0x67, 0x65, 0x6f } \
}
///
/// Variable name with guid EFI_IMAGE_SECURITY_DATABASE_GUID
/// for the authorized signature database.
///
#define EFI_IMAGE_SECURITY_DATABASE L"db"
///
/// Variable name with guid EFI_IMAGE_SECURITY_DATABASE_GUID
/// for the forbidden signature database.
///
#define EFI_IMAGE_SECURITY_DATABASE1 L"dbx"
#define SECURE_BOOT_MODE_ENABLE 1
#define SECURE_BOOT_MODE_DISABLE 0
#define SETUP_MODE 1
#define USER_MODE 0
///
/// Globally "SetupMode" variable to specify whether the system is currently operating
/// in setup mode (1) or not (0). All other values are reserved.
///
#define EFI_SETUP_MODE_NAME L"SetupMode"
///
/// Global "PK" variable for the Platform Key Signature Database.
///
#define EFI_PLATFORM_KEY_NAME L"PK"
///
/// Global "KEK" variable for the Key Exchange Key Signature Database.
///
#define EFI_KEY_EXCHANGE_KEY_NAME L"KEK"
///
/// Global "SignatureSupport" variable returns an array of GUIDs,
/// with each GUID representing a type of signature which the platform
/// firmware supports for images and other data.
///
#define EFI_SIGNATURE_SUPPORT_NAME L"SignatureSupport"
///
/// Global "SecureBoot" variable to specify whether the platform firmware
/// is operating in Secure boot mode (1) or not (0). All other values are reserved.
///
#define EFI_SECURE_BOOT_MODE_NAME L"SecureBoot"
//***********************************************************************
// Signature Database
//***********************************************************************
///
/// The format of a signature database.
///
#pragma pack(1)
typedef struct {
///
/// An identifier which identifies the agent which added the signature to the list.
///
EFI_GUID SignatureOwner;
///
/// The format of the signature is defined by the SignatureType.
///
UINT8 SignatureData[1];
} EFI_SIGNATURE_DATA;
typedef struct {
///
/// Type of the signature. GUID signature types are defined in below.
///
EFI_GUID SignatureType;
///
/// Total size of the signature list, including this header.
///
UINT32 SignatureListSize;
///
/// Size of the signature header which precedes the array of signatures.
///
UINT32 SignatureHeaderSize;
///
/// Size of each signature.
///
UINT32 SignatureSize;
///
/// Header before the array of signatures. The format of this header is specified
/// by the SignatureType.
/// UINT8 SignatureHeader[SignatureHeaderSize];
///
/// An array of signatures. Each signature is SignatureSize bytes in length.
/// EFI_SIGNATURE_DATA Signatures[][SignatureSize];
///
} EFI_SIGNATURE_LIST;
#pragma pack()
///
/// This identifies a signature containing a SHA-256 hash. The SignatureHeader size shall
/// always be 0. The SignatureSize shall always be 16 (size of SignatureOwner component) +
/// 32 bytes.
///
#define EFI_CERT_SHA256_GUID \
{ \
0xc1c41626, 0x504c, 0x4092, {0xac, 0xa9, 0x41, 0xf9, 0x36, 0x93, 0x43, 0x28} \
}
///
/// This identifies a signature containing an RSA-2048 key. The key (only the modulus
/// since the public key exponent is known to be 0x10001) shall be stored in big-endian
/// order.
/// The SignatureHeader size shall always be 0. The SignatureSize shall always be 16 (size
/// of SignatureOwner component) + 256 bytes.
///
#define EFI_CERT_RSA2048_GUID \
{ \
0x3c5766e8, 0x269c, 0x4e34, {0xaa, 0x14, 0xed, 0x77, 0x6e, 0x85, 0xb3, 0xb6} \
}
///
/// This identifies a signature containing a RSA-2048 signature of a SHA-256 hash. The
/// SignatureHeader size shall always be 0. The SignatureSize shall always be 16 (size of
/// SignatureOwner component) + 256 bytes.
///
#define EFI_CERT_RSA2048_SHA256_GUID \
{ \
0xe2b36190, 0x879b, 0x4a3d, {0xad, 0x8d, 0xf2, 0xe7, 0xbb, 0xa3, 0x27, 0x84} \
}
///
/// This identifies a signature containing a SHA-1 hash. The SignatureSize shall always
/// be 16 (size of SignatureOwner component) + 20 bytes.
///
#define EFI_CERT_SHA1_GUID \
{ \
0x826ca512, 0xcf10, 0x4ac9, {0xb1, 0x87, 0xbe, 0x1, 0x49, 0x66, 0x31, 0xbd} \
}
///
/// TThis identifies a signature containing a RSA-2048 signature of a SHA-1 hash. The
/// SignatureHeader size shall always be 0. The SignatureSize shall always be 16 (size of
/// SignatureOwner component) + 256 bytes.
///
#define EFI_CERT_RSA2048_SHA1_GUID \
{ \
0x67f8444f, 0x8743, 0x48f1, {0xa3, 0x28, 0x1e, 0xaa, 0xb8, 0x73, 0x60, 0x80} \
}
///
/// This identifies a signature based on an X.509 certificate. If the signature is an X.509
/// certificate then verification of the signature of an image should validate the public
/// key certificate in the image using certificate path verification, up to this X.509
/// certificate as a trusted root. The SignatureHeader size shall always be 0. The
/// SignatureSize may vary but shall always be 16 (size of the SignatureOwner component) +
/// the size of the certificate itself.
/// Note: This means that each certificate will normally be in a separate EFI_SIGNATURE_LIST.
///
#define EFI_CERT_X509_GUID \
{ \
0xa5c059a1, 0x94e4, 0x4aa7, {0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72} \
}
///
/// This identifies a signature containing a SHA-224 hash. The SignatureHeader size shall
/// always be 0. The SignatureSize shall always be 16 (size of SignatureOwner component) +
/// 28 bytes.
///
#define EFI_CERT_SHA224_GUID \
{ \
0xb6e5233, 0xa65c, 0x44c9, {0x94, 0x7, 0xd9, 0xab, 0x83, 0xbf, 0xc8, 0xbd} \
}
///
/// This identifies a signature containing a SHA-384 hash. The SignatureHeader size shall
/// always be 0. The SignatureSize shall always be 16 (size of SignatureOwner component) +
/// 48 bytes.
///
#define EFI_CERT_SHA384_GUID \
{ \
0xff3e5307, 0x9fd0, 0x48c9, {0x85, 0xf1, 0x8a, 0xd5, 0x6c, 0x70, 0x1e, 0x1} \
}
///
/// This identifies a signature containing a SHA-512 hash. The SignatureHeader size shall
/// always be 0. The SignatureSize shall always be 16 (size of SignatureOwner component) +
/// 64 bytes.
///
#define EFI_CERT_SHA512_GUID \
{ \
0x93e0fae, 0xa6c4, 0x4f50, {0x9f, 0x1b, 0xd4, 0x1e, 0x2b, 0x89, 0xc1, 0x9a} \
}
///
/// This identifies a signature containing a DER-encoded PKCS #7 version 1.5 [RFC2315]
/// SignedData value.
///
#define EFI_CERT_TYPE_PKCS7_GUID \
{ \
0x4aafd29d, 0x68df, 0x49ee, {0x8a, 0xa9, 0x34, 0x7d, 0x37, 0x56, 0x65, 0xa7} \
}
//***********************************************************************
// Image Execution Information Table Definition
//***********************************************************************
typedef UINT32 EFI_IMAGE_EXECUTION_ACTION;
#define EFI_IMAGE_EXECUTION_AUTHENTICATION 0x00000007
#define EFI_IMAGE_EXECUTION_AUTH_UNTESTED 0x00000000
#define EFI_IMAGE_EXECUTION_AUTH_SIG_FAILED 0x00000001
#define EFI_IMAGE_EXECUTION_AUTH_SIG_PASSED 0x00000002
#define EFI_IMAGE_EXECUTION_AUTH_SIG_NOT_FOUND 0x00000003
#define EFI_IMAGE_EXECUTION_AUTH_SIG_FOUND 0x00000004
#define EFI_IMAGE_EXECUTION_POLICY_FAILED 0x00000005
#define EFI_IMAGE_EXECUTION_INITIALIZED 0x00000008
//
// EFI_IMAGE_EXECUTION_INFO is added to EFI System Configuration Table
// and assigned the GUID EFI_IMAGE_SECURITY_DATABASE_GUID.
//
typedef struct {
///
/// Describes the action taken by the firmware regarding this image.
///
EFI_IMAGE_EXECUTION_ACTION Action;
///
/// Size of all of the entire structure.
///
UINT32 InfoSize;
///
/// If this image was a UEFI device driver (for option ROM, for example) this is the
/// null-terminated, user-friendly name for the device. If the image was for an application,
/// then this is the name of the application. If this cannot be determined, then a simple
/// NULL character should be put in this position.
/// CHAR16 Name[];
///
///
/// For device drivers, this is the device path of the device for which this device driver
/// was intended. In some cases, the driver itself may be stored as part of the system
/// firmware, but this field should record the device's path, not the firmware path. For
/// applications, this is the device path of the application. If this cannot be determined,
/// a simple end-of-path device node should be put in this position.
/// EFI_DEVICE_PATH_PROTOCOL DevicePath;
///
///
/// Zero or more image signatures. If the image contained no signatures,
/// then this field is empty.
///
EFI_SIGNATURE_LIST Signature;
} EFI_IMAGE_EXECUTION_INFO;
typedef struct {
///
/// Number of EFI_IMAGE_EXECUTION_INFO structures.
///
UINTN NumberOfImages;
///
/// Number of image instances of EFI_IMAGE_EXECUTION_INFO structures.
///
// EFI_IMAGE_EXECUTION_INFO InformationInfo[]
} EFI_IMAGE_EXECUTION_INFO_TABLE;
extern EFI_GUID gEfiImageSecurityDatabaseGuid;
extern EFI_GUID gEfiCertSha256Guid;
extern EFI_GUID gEfiCertRsa2048Guid;
extern EFI_GUID gEfiCertRsa2048Sha256Guid;
extern EFI_GUID gEfiCertSha1Guid;
extern EFI_GUID gEfiCertRsa2048Sha1Guid;
extern EFI_GUID gEfiCertX509Guid;
extern EFI_GUID gEfiCertSha224Guid;
extern EFI_GUID gEfiCertSha384Guid;
extern EFI_GUID gEfiCertSha512Guid;
extern EFI_GUID gEfiCertPkcs7Guid;
#endif
@@ -0,0 +1,33 @@
/* secKeyStoreP.h - #BRIEF# library header file */
/*
* Copyright (c) 2015, 2020-2021 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
#ifndef __INCsecKeyStorePh
#define __INCsecKeyStorePh
/* includes */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* defines */
/* typedefs */
/* function declarations */
void* secKeyStoreOpen(void);
int secKeyStoreRead(void* handle, char* name, int len);
STATUS secKeyStoreClose(void* handle);
STATUS secKeyStoreReadyCheck();
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __INCsecKeyStorePh */
@@ -0,0 +1,122 @@
/* secSecretP.h - secSecret private header file */
/*
* Copyright (c) 2015-2017, 2019, 2021 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
#ifndef __INCsecSecretPh
#define __INCsecSecretPh
/* includes */
#include <secSecret.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* defines */
#ifndef SEC_SECRET_PATH_MAX
#define SEC_SECRET_PATH_MAX 128
#endif
#define SEC_SECRET_TYPE_PKEY 1
#define SEC_SECRET_TYPE_TPM2_KEY 2
#define SEC_SECRET_TYPE_OPAQUE 4
#define SEC_SECRET_MODE_READ 1
#define SEC_SECRET_MODE_WRITE 2
/* Variables */
/* typedefs */
/* function declarations */
/*******************************************************************************
*
* secSecretOpen - open the database for reading
*
* This routine returns a handle that can be used to iterate all key IDs in the
* database. Note that public keys and buffers/pre-shared keys have different
* name spaces.
*
* RETURNS: A handle to be used in subsequent calls to secSecretRead
* and secSecretClose.
* NULL in case of error.
*
* ERRNO:
*/
void* secSecretOpen(void);
/*******************************************************************************
*
* secSecretRead - return next key ID from the database
*
* This routine returns the next key ID from the database.
*
* Parameter:
* \is
* \i <handle>
* handle returned from secSecretOpen
* \i <name>
* buffer to store the key ID in
* \i <name>
* length of name buffer
* \ie
*
* RETURNS:
* IPCOM_SUCCESS if successful
* IPCOM_ERR_END if no more entries can be read
* IPCOM_ERR_FAILED in case of error
*
* ERRNO:
*/
int secSecretRead(void* handle, char* name, int name_len);
/*******************************************************************************
*
* secSecretClose - close handle
*
* This routine closes a handle used to iterate all key IDs in the
* database.
*
* Parameter:
* \is
* \i <handle>
* handle returned from secSecretOpen
* \ie
*
* RETURNS:
* OK if the handle was closed
* ERROR if the handle could not be closed;
*
* ERRNO:
*/
int secSecretClose(void* handle);
void* secSecretOpenDir(int type);
void secSecretInit(const char* rootDir);
int secSecretKepGet(char* buf, int* len);
FILE* secSecretFpGet(const char* keyId, int type, int mode);
void secSecretLock(void);
void secSecretUnlock(void);
STATUS secSecretGetDirPath(const int type, char* filePath, size_t pathLen);
STATUS secSecretGetFilePath(const char* keyId, const int type, char* filePath, size_t pathLen);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __INCsecSecretPh */
@@ -0,0 +1,49 @@
/* secUefiDbP.h - secUefiDb private header file */
/*
* Copyright (c) 2017, 2021 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
#ifndef __INCsecUefiDbPh
#define __INCsecUefiDbPh
/* includes */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* defines */
/* Variables */
/* typedefs */
#ifdef _WRS_CONFIG_LP64
typedef uint64_t UINTN;
#else
typedef uint32_t UINTN;
#endif
/* Introduced from header efidef.h from gnu-efi-3.0 */
typedef struct {
UINT32 Data1;
UINT16 Data2;
UINT16 Data3;
UINT8 Data4[8];
} EFI_GUID;
extern const char uefiDatabase[];
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __INCsecUefiDbPh */
@@ -0,0 +1,44 @@
/* secVaultP.h - wrapper header file for secSecretP.h */
/*
* Copyright (c) 2015-2017, 2021 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
#ifndef __INCsecVaultPh
#define __INCsecVaultPh
/* includes */
#include <secSecret.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* defines */
#define SEC_VAULT_PATH_MAX SEC_SECRET_PATH_MAX
#define SEC_VAULT_TYPE_PKEY SEC_SECRET_TYPE_PKEY
#define SEC_VAULT_TYPE_OPAQUE SEC_SECRET_TYPE_OPAQUE
#define SEC_VAULT_MODE_READ SEC_SECRET_MODE_READ
#define SEC_VAULT_MODE_WRITE SEC_SECRET_MODE_WRITE
#define secVaultOpen() secSecretOpen()
#define secVaultRead(handle, name,name_len) secSecretRead(handle, name,name_len)
#define secVaultClose(handle) secSecretClose(handle)
#ifdef __cplusplus
}
#endif /* __cplusplus */
#include <private/secSecretP.h>
#endif /* __INCsecVaultPh */
@@ -0,0 +1,47 @@
/* uefiTrustStoreP.h - private header file for UEFI trust store */
/*
* Copyright (c) 2017, 2021 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
DESCRIPTION
This header file describes the private definitions and structures
for the UEFI database trust store.
*/
#ifndef __INCuefiTrustStorePh
#define __INCuefiTrustStorePh
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* includes */
/* defines */
#define SECURE_LOADER_DB_SECTION ".uefi_db"
#define UEFI_DATABASE_VERSION 1 /* current version */
/* typedefs */
typedef struct
{
uint32_t version; /* version number */
uint32_t padding; /* add padding for alignment */
uint64_t white_db_size; /* whitelist database size in bytes */
uint64_t black_db_size; /* blacklist database size in bytes */
char efiSignatureList[1]; /* place holder for start of signature list */
} UEFI_DB_INFO;
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* INCuefiTrustStorePh */
+149
View File
@@ -0,0 +1,149 @@
/* secCrypto.h - SEC_CRYPTO library header file */
/*
* Copyright (c) 2014-2015, 2017-2018, 2021 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
#ifndef __INCsecCryptoh
#define __INCsecCryptoh
/* includes */
#include <vxWorks.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* defines */
#define SEC_CRYPTO_ID_BASE 1000
#define SEC_CRYPTO_ID_AES_128_CBC 1 + SEC_CRYPTO_ID_BASE
#define SEC_CRYPTO_ID_AES_192_CBC 2 + SEC_CRYPTO_ID_BASE
#define SEC_CRYPTO_ID_AES_256_CBC 3 + SEC_CRYPTO_ID_BASE
#define SEC_CRYPTO_ID_AES_128_CTR 4 + SEC_CRYPTO_ID_BASE
#define SEC_CRYPTO_ID_AES_192_CTR 5 + SEC_CRYPTO_ID_BASE
#define SEC_CRYPTO_ID_AES_256_CTR 6 + SEC_CRYPTO_ID_BASE
#define SEC_CRYPTO_ID_AES_128_ECB 8 + SEC_CRYPTO_ID_BASE
#define SEC_CRYPTO_ID_AES_256_ECB 9 + SEC_CRYPTO_ID_BASE
#define SEC_CRYPTO_ID_CAST_CBC 10 + SEC_CRYPTO_ID_BASE
#define SEC_CRYPTO_ID_DES_CBC 11 + SEC_CRYPTO_ID_BASE
#define SEC_CRYPTO_ID_3DES_CBC 12 + SEC_CRYPTO_ID_BASE
#define SEC_CRYPTO_ID_RC4 13 + SEC_CRYPTO_ID_BASE
#define SEC_CRYPTO_ID_BF_CBC 14 + SEC_CRYPTO_ID_BASE
#define SEC_CIPHER_DECR 0
#define SEC_CIPHER_ENCR 1
#define SEC_CIPHER_FLAG_ENCR 1
#define SEC_CIPHER_FLAG_PKCS_PAD (1 << 1)
#define SEC_CIPHER_CTRL_SET_PADDING 1
#define SEC_CIPHER_CTRL_GET_PADDING 2
#define SEC_CIPHER_CTRL_ENCR 3
#define SEC_CIPHER_CTRL_DECR 4
#define SEC_CIPHER_CTRL_GET_IV 5
#define SEC_CIPHER_CTRL_SET_IV 6
#define SEC_CIPHER_MAX_BLOCK_SIZE 32
#define SEC_CIPHER_AES_BLOCK_SIZE 16
/* typedefs */
struct SEC_CIPHER_CTX_ST;
typedef struct SEC_HASH_TEMPLATE_ST SEC_HASH_TEMPLATE;
typedef struct SEC_CIPHER_TEMPLATE_ST
{
int type;
int blockSize; /* bytes */
int keyLen; /* bytes */
int ivLen; /* bytes */
int (*cipherInit)(struct SEC_CIPHER_CTX_ST* ctx,
const unsigned char *key,
const unsigned char *iv,
const int encr);
int (*cipherUpdate)(struct SEC_CIPHER_CTX_ST* ctx, unsigned char* out, int* outLen, const unsigned char* in,int inLen);
int (*final)(struct SEC_CIPHER_CTX_ST* ctx, unsigned char* out, int* outLen);
int (*ctrl)(struct SEC_CIPHER_CTX_ST* ctx, int type, void* arg, unsigned int* len);
int (*cleanup)(struct SEC_CIPHER_CTX_ST* ctx);
int (*copy)(struct SEC_CIPHER_CTX_ST* copy, struct SEC_CIPHER_CTX_ST* org);
} SEC_CIPHER_TEMPLATE;
typedef struct SEC_CIPHER_CTX_ST
{
const SEC_CIPHER_TEMPLATE* cipher;
unsigned long flags;
void* ctxData;
unsigned char cache[SEC_CIPHER_MAX_BLOCK_SIZE]; /* Place to store temporary bytes when cipherUpdate input is not a full block */
unsigned int cachedBytes; /* Number of bytes currently stored in cache */
unsigned char finalCache[SEC_CIPHER_MAX_BLOCK_SIZE]; /* Place to temporarily store the last decrypted block when padding is used */
unsigned int finalCachedBytes; /* Number of bytes currently stored in cache */
} SEC_CIPHER_CTX ;
/* function declarations */
STATUS secCipherInit(SEC_CIPHER_CTX* ctx, const SEC_CIPHER_TEMPLATE* cipherTemplate, const unsigned char* key, const unsigned char* iv, const int encr);
STATUS secCipherUpdate(SEC_CIPHER_CTX* ctx, unsigned char* out, int* outLen, const unsigned char* in,int inLen);
STATUS secCipherFinal(SEC_CIPHER_CTX* ctx, unsigned char* out, int* outLen);
STATUS secCipherCtrl(SEC_CIPHER_CTX* ctx, int type, void* arg, unsigned int* len);
STATUS secCipherCleanup(SEC_CIPHER_CTX* ctx);
STATUS secCipherCopy(SEC_CIPHER_CTX* copy, SEC_CIPHER_CTX* org);
/*
* Sets the default template functions.
* These APIs are used to register a new provider of an encryption algorithm.
*/
void secCipherAes128CbcTemplateSet(const SEC_CIPHER_TEMPLATE* ctx);
void secCipherAes128CtrTemplateSet(const SEC_CIPHER_TEMPLATE* ctx);
void secCipherAes128EcbTemplateSet(const SEC_CIPHER_TEMPLATE* ctx);
void secCipherAes192CbcTemplateSet(const SEC_CIPHER_TEMPLATE* ctx);
void secCipherAes192CtrTemplateSet(const SEC_CIPHER_TEMPLATE* ctx);
void secCipherAes256CbcTemplateSet(const SEC_CIPHER_TEMPLATE* ctx);
void secCipherAes256CtrTemplateSet(const SEC_CIPHER_TEMPLATE* ctx);
void secCipherAes256EcbTemplateSet(const SEC_CIPHER_TEMPLATE* ctx);
void secCipherAesCtrTemplateSet(const SEC_CIPHER_TEMPLATE* ctx);
void secCipherBlowfishCbcTemplateSet(const SEC_CIPHER_TEMPLATE* ctx);
void secCipherCastCbcTemplateSet(const SEC_CIPHER_TEMPLATE* ctx);
void secCipherDesCbcTemplateSet(const SEC_CIPHER_TEMPLATE* ctx);
void secCipher3DesCbcTemplateSet(const SEC_CIPHER_TEMPLATE* ctx);
void secCipherRc4TemplateSet(const SEC_CIPHER_TEMPLATE* ctx);
/*
* These APIs are used to fetch the default template for
* symmetrical encryption algorithms.
*/
const SEC_CIPHER_TEMPLATE* secCipherAes128CbcTemplateGet(void);
const SEC_CIPHER_TEMPLATE* secCipherAes128CtrTemplateGet(void);
const SEC_CIPHER_TEMPLATE* secCipherAes128EcbTemplateGet(void);
const SEC_CIPHER_TEMPLATE* secCipherAes192CbcTemplateGet(void);
const SEC_CIPHER_TEMPLATE* secCipherAes192CtrTemplateGet(void);
const SEC_CIPHER_TEMPLATE* secCipherAes256CbcTemplateGet(void);
const SEC_CIPHER_TEMPLATE* secCipherAes256CtrTemplateGet(void);
const SEC_CIPHER_TEMPLATE* secCipherAes256EcbTemplateGet(void);
const SEC_CIPHER_TEMPLATE* secCipherBlowfishCbcTemplateGet(void);
const SEC_CIPHER_TEMPLATE* secCipherCastCbcTemplateGet(void);
const SEC_CIPHER_TEMPLATE* secCipherDesCbcTemplateGet(void);
const SEC_CIPHER_TEMPLATE* secCipher3DesCbcTemplateGet(void);
const SEC_CIPHER_TEMPLATE* secCipherRc4TemplateGet(void);
STATUS secKeyIvGen(const char* pw,
const size_t pwLen,
unsigned char* key,
int keyLen,
unsigned char* iv,
int ivLen,
const SEC_HASH_TEMPLATE* hashTemplate);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __INCsecCryptoh */
@@ -0,0 +1,53 @@
/* secCipherXexAes.h - XEX-AES Private Header File */
/*
* Copyright (c) 2016-2017, 2021 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
#ifndef __INCsecCipherXexAesh
#define __INCsecCipherXexAesh
/* includes */
#include <types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <vxWorks.h>
#include <secCrypto.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* typedefs */
typedef struct secXexAesCtx
{
SEC_CIPHER_CTX key1EncrCtx;
SEC_CIPHER_CTX key1DecrCtx;
SEC_CIPHER_CTX key2EncrCtx;
size_t sectorSize;
long long sectorNum;
UINT8 * pSectorTweak;
} SEC_XEX_AES_CTX;
/* function declarations */
STATUS secXexAesInit (SEC_XEX_AES_CTX * pCtx, const SEC_CIPHER_TEMPLATE *
pAesCipher, UINT8* key1, UINT8* key2, size_t sectorSize);
STATUS secXexAesUpdate (SEC_XEX_AES_CTX * pCtx, unsigned char * out, int *
outLen, const unsigned char * in, int inLen, long long
sectorNum, int encr);
STATUS secXexAesCleanup (SEC_XEX_AES_CTX * pCtx);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __INCsecCipherXexAesh */
+141
View File
@@ -0,0 +1,141 @@
/* secHash.h - SEC_HASH library header file */
/*
* Copyright (c) 2015, 2017, 2021 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/* includes */
#ifndef __INCsecHashh
#define __INCsecHashh
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* defines */
/* typedefs */
/* function declarations */
#include <vxWorks.h>
#define SEC_HASH_ID_BASE 0
#define SEC_HASH_ID_MD5 1 + SEC_HASH_ID_BASE
#define SEC_HASH_ID_SHA1 2 + SEC_HASH_ID_BASE
#define SEC_HASH_ID_SHA256 3 + SEC_HASH_ID_BASE
#define SEC_HASH_ID_SHA384 4 + SEC_HASH_ID_BASE
#define SEC_HASH_ID_SHA512 5 + SEC_HASH_ID_BASE
#define SEC_HASH_ID_RMD 6 + SEC_HASH_ID_BASE
#define SEC_HASH_ID_WHIRLPOOL 6 + SEC_HASH_ID_BASE
#define SEC_HASH_DIGEST_LEN_MD5 16
#define SEC_HASH_DIGEST_LEN_RMD 20
#define SEC_HASH_DIGEST_LEN_SHA1 20
#define SEC_HASH_DIGEST_LEN_SHA256 32
#define SEC_HASH_DIGEST_LEN_SHA384 48
#define SEC_HASH_DIGEST_LEN_SHA512 64
#define SEC_HASH_DIGEST_LEN_WHIRLPOOL 64
#define SEC_HASH_DIGEST_LEN_MAX 64
struct SEC_HASH_CTX_ST;
struct SEC_HASH_TEMPLATE_ST;
typedef struct SEC_HASH_TEMPLATE_ST
{
int type;
int md_size;
int blockSize;
STATUS (*init)(struct SEC_HASH_CTX_ST* ctx, const struct SEC_HASH_TEMPLATE_ST* hash_template);
STATUS (*update)(struct SEC_HASH_CTX_ST* ctx,const void* data,size_t count);
STATUS (*final)(struct SEC_HASH_CTX_ST* ctx,unsigned char* digest, unsigned int* digestLen);
STATUS (*ctrl)(struct SEC_HASH_CTX_ST* ctx, int type, void* arg, unsigned int* len);
STATUS (*copy)(struct SEC_HASH_CTX_ST* copy, struct SEC_HASH_CTX_ST* org);
void (*cleanup)(struct SEC_HASH_CTX_ST* ctx);
} SEC_HASH_TEMPLATE;
typedef struct SEC_HASH_CTX_ST
{
const SEC_HASH_TEMPLATE* hash;
unsigned long flags;
char* data;
} SEC_HASH_CTX;
/* Use secHash() if you have one consecutive memory segment to hash */
STATUS secHash(const void* data, size_t len, unsigned char* digest, unsigned int *out_len, const SEC_HASH_TEMPLATE* hash_template);
/* Use secHashInit(), secHashUpdate(), secHashFinal(), and secHashCleanup() if the memory you need to hash
* is divided into two or more segments. Note that each call to secHashInit() must be matched by a
* call to secHashCleanup().
*
* A normal call sequence would be:
* SEC_HASH_CTX ctx;
* secHashInit(&ctx, secHashSha256Templ());
* secHashUpdate(&ctx, data1, len1);
* secHashUpdate(&ctx, data2, len2);
* secHashUpdate(&ctx, data3, len3);
* secHashFinal(&ctx, digest, &dgst_len);
* secHashCleanup(&ctx);
*/
STATUS secHashInit(SEC_HASH_CTX* ctx, const SEC_HASH_TEMPLATE* hash_template);
STATUS secHashUpdate(SEC_HASH_CTX* ctx, const void* data, size_t count);
STATUS secHashFinal(SEC_HASH_CTX* ctx, unsigned char* digest, unsigned int* digestLen);
STATUS secHashCtrl(struct SEC_HASH_CTX_ST* ctx, int type, void* arg, unsigned int* len);
void secHashCleanup(SEC_HASH_CTX* ctx);
/* Use secHashCopy if you need to pre-compute some hashes, and re-use the pre-computed hashes.
* Note that every call to secHashCopy, must be matched by a call to secHashCleanup().
*
* A normal call sequence would be:
* SEC_HASH_CTX ctx, ctx2;
* secHashInit(&ctx, secHashSha256Templ());
* secHashUpdate(&ctx, data1, len1);
* secHashCopy(&ctx2, &ctx);
* secHashUpdate(&ctx, data2, len2);
* secHashFinal(&ctx, digest, &dgst_len);
* secHashCleanup(&ctx);
*
* secHashUpdate(&ctx2, data3, len3);
* secHashFinal(&ctx2, digest2, &dgst_len2);
* secHashCleanup(&ctx2);
*
* The hash result in digest2 is the same as if the following code had been used:
* SEC_HASH_CTX, ctx2;
* secHashInit(&ctx2, secHashSha256Templ());
* secHashUpdate(&ctx2, data1, len1);
* secHashUpdate(&ctx2, data3, len3);
* secHashFinal(&ctx, digest2, &dgst_len2);
* secHashCleanup(&ctx2);
*/
STATUS secHashCopy(SEC_HASH_CTX* copy, SEC_HASH_CTX* org);
/* Sets the default template functions. These APIs are used to register a new provider
* of a hash algorithm */
void secHashMd5TemplateSet(const SEC_HASH_TEMPLATE* ctx);
void secHashRmdTemplateSet(const SEC_HASH_TEMPLATE* ctx);
void secHashSha1TemplateSet(const SEC_HASH_TEMPLATE* ctx);
void secHashSha256TemplateSet(const SEC_HASH_TEMPLATE* ctx);
void secHashSha384TemplateSet(const SEC_HASH_TEMPLATE* ctx);
void secHashSha512TemplateSet(const SEC_HASH_TEMPLATE* ctx);
void secHashWhirlpoolTemplateSet(const SEC_HASH_TEMPLATE* ctx);
/* These APIs are used to fetch the default template for hash algorithms */
const SEC_HASH_TEMPLATE* secHashMd5TemplateGet(void);
const SEC_HASH_TEMPLATE* secHashRmdTemplateGet(void);
const SEC_HASH_TEMPLATE* secHashSha1TemplateGet(void);
const SEC_HASH_TEMPLATE* secHashSha256TemplateGet(void);
const SEC_HASH_TEMPLATE* secHashSha384TemplateGet(void);
const SEC_HASH_TEMPLATE* secHashSha512TemplateGet(void);
const SEC_HASH_TEMPLATE* secHashWhirlpoolTemplateGet(void);
#ifdef __cplusplus
}
#endif
#endif /* __INCsecHashh */
+47
View File
@@ -0,0 +1,47 @@
/* secHmac.h - HMAC library header file */
/*
* Copyright (c) 2015, 2021 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
#ifndef __INCsecHmach
#define __INCsecHmach
/* includes */
#include <secHash.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* defines */
#define SEC_HMAC_MAX_BLOCK 128
/* typedefs */
struct SEC_HMAC_CTX_ST
{
SEC_HASH_CTX hashCtx;
unsigned char k_ipad[SEC_HMAC_MAX_BLOCK];
unsigned char k_opad[SEC_HMAC_MAX_BLOCK];
unsigned int keyLen;
};
typedef struct SEC_HMAC_CTX_ST SEC_HMAC_CTX;
/* function declarations */
STATUS secHmacInit(SEC_HMAC_CTX* ctx, const unsigned char* key, int keyLen, const SEC_HASH_TEMPLATE* hashTemplate);
STATUS secHmacUpdate(SEC_HMAC_CTX* ctx, const unsigned char* data, unsigned int dataLen);
STATUS secHmacFinal(SEC_HMAC_CTX* ctx, unsigned char* hmac, unsigned int* hmacLen);
void secHmacCleanup(SEC_HMAC_CTX* ctx);
STATUS secHmac(const unsigned char* key, int keyLen, unsigned char* data, unsigned int dataLen,
unsigned char* hmac, unsigned int* hmacLen, const SEC_HASH_TEMPLATE* hashTemplate);
STATUS secHmacCopy(SEC_HMAC_CTX* copy, SEC_HMAC_CTX* org);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __INCsecHmach */
@@ -0,0 +1,47 @@
/* secKeyStore.h - VxWorks Key Store library header file */
/*
* Copyright (c) 2015, 2021 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
#ifndef __INCsecKeyStoreh
#define __INCsecKeyStoreh
/* includes */
#include <secSecret.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* defines */
/* typedefs */
struct evp_pkey_st;
struct x509_st;
/* function declarations */
struct evp_pkey_st* secKeyStoreGet(const char* key_id);
struct evp_pkey_st* secKeyStoreX509Get(struct x509_st* x509,
char* id,
int* len);
int secKeyStoreImport(const char* key_id,
struct evp_pkey_st* key);
int secKeyStoreDel(const char* key_id);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __INCsecKeyStoreh */
+42
View File
@@ -0,0 +1,42 @@
/* secPbkdf2.h - PBKDF2 library header file */
/*
* Copyright (c) 2015, 2021 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
#ifndef __INCsecPbkdf2h
#define __INCsecPbkdf2h
/* includes */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* defines */
/* typedefs */
/* function declarations */
STATUS secPbkdf2Hmac
(
const char *pw,
int pwLen,
const unsigned char *salt,
int saltLen,
int c,
const SEC_HASH_TEMPLATE *hash,
int keyLen,
unsigned char *key
);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __INCsecPbkdf2h */
+69
View File
@@ -0,0 +1,69 @@
/* secSecret.h - vault secret library header file */
/*
* Copyright (c) 2015-2017, 2021 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
#ifndef __INCsecSecreth
#define __INCsecSecreth
/* includes */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* defines */
#ifndef SEC_SECRET_KEY_ID_MAX
#define SEC_SECRET_KEY_ID_MAX 64
#endif
#ifndef SEC_SECRET_MAX_SECRET
#define SEC_SECRET_MAX_SECRET 256
#endif
/* typedefs */
typedef struct secKepBackend
{
STATUS (*kepGet) /* get KEP from backend */
(
char * buf,
int * len
);
}SEC_VAULT_KEP_BACKEND;
/* deprecated type */
typedef int (*SEC_VAULT_KEP_CB)(char* buf, int* len);
/* function declarations */
/* secure vault */
int secSecretImport (const char * keyId, const char * key, int keyLen);
int secSecretGet (const char * keyId, char * key, int * keyLen);
int secSecretDel (const char * keyId);
BOOL secSecretReadyCheck (const int delaySeconds);
STATUS securePartitionWaitMount (const char * pPartName);
/* KEP backend */
STATUS secVaultKepBackendSet (SEC_VAULT_KEP_BACKEND * pBackend);
STATUS secSecretKepGet (char * buf, int * len);
/* deprecated API */
int secVaultSetKepCb (SEC_VAULT_KEP_CB callback);
SEC_VAULT_KEP_CB secSecretGetKepCb (void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __INCsecSecreth */
@@ -0,0 +1,49 @@
/* secTrustStore.h - VxWorks trust store library header file */
/*
* Copyright (c) 2017, 2021, 2023 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
#ifndef __INCsecTrustStoreh
#define __INCsecTrustStoreh
/* includes */
#include <vxWorks.h>
#include <openssl/x509.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* defines */
/* KeyUsage defines */
#define DIGITAL_SIGNATURE (1)
#define CONTENT_COMMITMENT (1<<1) /* previous editions of X.509
called this bit to nonRepudiation */
#define KEY_ENCIPHERMENT (1<<2)
#define DATA_ENCIPHERMENT (1<<3)
#define KEY_AGREEMENT (1<<4)
#define KEY_CERT_SIGN (1<<5)
#define CRL_SIGN (1<<6)
#define ENCIPHER_ONLY (1<<7)
#define DECIPHER_ONLY (1<<8)
/* typedefs */
typedef STATUS (*SEC_TRUST_STORE_PUBKEY_VALIDATE_CB)(const char* trustStoreId, const X509* cert, const unsigned int keyUsage);
/* function declarations */
extern STATUS secTrustStorePubKeyValidate(const char* trustStoreId, const X509* cert, const unsigned int keyUsage);
extern void secTrustStorePubKeyValidateProviderSet(const SEC_TRUST_STORE_PUBKEY_VALIDATE_CB provider);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __INCsecTrustStoreh */
+89
View File
@@ -0,0 +1,89 @@
/* secVault.h - Secrets repository library header file */
/*
* Copyright (c) 2015-2017, 2021 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
#ifndef __INCsecVaulth
#define __INCsecVaulth
/* includes */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* defines */
#define SEC_VAULT_KEY_ID_MAX SEC_SECRET_KEY_ID_MAX
#define SEC_VAULT_MAX_SECRET SEC_SECRET_MAX_SECRET
#include <secSecret.h>
LOCAL int secVaultImport (const char * keyId, const char * key, int keyLen) _WRS_DEPRECATED("secVaultImport is deprecated. Use secSecretImport instead");
_WRS_INLINE int secVaultImport
(
const char * keyId,
const char * key,
int keyLen
)
{
return secSecretImport(keyId, key, keyLen);
}
LOCAL int secVaultGet (const char * keyId, char * key, int * keyLen) _WRS_DEPRECATED("secVaultGet is deprecated. Use secSecretGet instead");
_WRS_INLINE int secVaultGet
(
const char * keyId,
char * key,
int * keyLen
)
{
return (secSecretGet (keyId, key, keyLen));
}
LOCAL int secVaultDel (const char * keyId) _WRS_DEPRECATED("secVaultDel is deprecated. Use secSecretDel instead");
_WRS_INLINE int secVaultDel
(
const char * keyId
)
{
return secSecretDel(keyId);
}
/* KEP backend */
LOCAL STATUS secVaultKepGet (char * buf, int * len) _WRS_DEPRECATED("secVaultKepGet is deprecated. Use secSecretKepGet instead");
_WRS_INLINE STATUS secVaultKepGet
(
char * buf, int * len
)
{
return secSecretKepGet(buf, len);
}
LOCAL SEC_VAULT_KEP_CB secVaultGetKepCb (void) _WRS_DEPRECATED("secVaultGetKepCb is deprecated. Use secSecretGetKepCb instead");
_WRS_INLINE SEC_VAULT_KEP_CB secVaultGetKepCb
(
void
)
{
return secSecretGetKepCb();
}
/* typedefs */
/* function declarations */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __INCsecVaulth */
@@ -0,0 +1,11 @@
# Makefile - openSSL layer Makefile
#
# Copyright (c) 2014, 2016, 2018, 2021 Wind River Systems, Inc.
#
# The right to copy, distribute, modify or otherwise make use
# of this software may be licensed only pursuant to the terms
# of an applicable Wind River license agreement.
#
include $(WIND_KRNL_MK)/rules.layers.mk
@@ -0,0 +1,38 @@
# Makefile - SECURITY_MISC SEC_CRYPTO layer Makefile
#
# Copyright (c) 2019, 2021 Wind River Systems, Inc.
#
# The right to copy, distribute, modify or otherwise make use
# of this software may be licensed only pursuant to the terms
# of an applicable Wind River license agreement.
#
include $(WIND_KRNL_MK)/defs.layers.mk
# When using the SEC_CRYPTO encryption API, you must include OPENSSL
# or provide your own set of encryption algorithm implementations.
# If you provide your own set of encryption algorithm implementations,
# you can disable the WR implementation by setting the WR_OPENSSL_DISABLED=y
# in a common.vxconfig file in the new layer
# if CRYPTO_SUPPORTED is not set then fail with an error
ifdef _WRS_CONFIG_SEC_CRYPTO
KERNEL_PUBLIC_H_DIRS += h
KERNEL_PROTECTED_H_DIRS += protectedh
BUILD_DIRS += src
POST_NOBUILD_CDFDIRS += cdf
POST_NOBUILD_CFGDIRS += cfg
endif
ifneq ("$(wildcard vxTest/src/Makefile)","")
ifdef _WRS_CONFIG_SEC_CRYPTO_VXTEST
BUILD_DIRS += vxTest/src
POST_NOBUILD_CDFDIRS += vxTest/cdf
endif
endif
CC_WARNINGS_BUILD_DIRS = CC_WARNINGS_HIGH_SYS
CC_WARNINGS_BUILD_USER_DIRS = CC_WARNINGS_HIGH_SYS
include $(WIND_KRNL_MK)/rules.layers.mk
@@ -0,0 +1,70 @@
# Makefile - makefile for secCrypto
#
# Copyright (c) 2014-2022 Wind River Systems, Inc.
#
# The right to copy, distribute, modify or otherwise make use
# of this software may be licensed only pursuant to the terms
# of an applicable Wind River license agreement.
#
# DESCRIPTION
# Makefile for secCrypto
#
LIB_BASE_NAME = SECCRYPTO
include $(WIND_KRNL_MK)/defs.library.mk
ifdef _WRS_CONFIG_CORE__BANNED_H
ADDED_CFLAGS += -include banned.h
endif
ifdef _WRS_ALL_DOCS
DOC_FILES = secKeyStoreLib.c secSecretLib.c secCipher.c secTrustStoreLib.c
else
DOC_FILES = secKeyStoreLib.c secCipher.c secTrustStoreLib.c
OBJS += secCipher.o
OBJS += secCipherAes128Cbc.o
OBJS += secCipherAes128Ctr.o
OBJS += secCipherAes128Ecb.o
OBJS += secCipherAes192Cbc.o
OBJS += secCipherAes192Ctr.o
OBJS += secCipherAes256Cbc.o
OBJS += secCipherAes256Ctr.o
OBJS += secCipherAes256Ecb.o
OBJS += secCipherBlowfishCbc.o
OBJS += secCipherCastCbc.o
OBJS += secCipherDesCbc.o
OBJS += secCipher3DesCbc.o
OBJS += secCipherRc4.o
OBJS += secKeyStoreLib.o
OBJS += secTrustStoreLib.o secTrustStoreStaticProvider.o
ifdef _WRS_CONFIG_ARCH_i86
OBJS += secTrustStoreUefiProvider.o
endif
ifdef _WRS_CONFIG_FSL_IMX
OBJS += secTrustStoreImxProvider.o
endif
ifdef _WRS_CONFIG_SHELL
OBJS += secKeyStoreCmd.o
endif
ifdef _WRS_CONFIG_IPNET_COREIP
ifdef _WRS_CONFIG_SHELL
OBJS += ipcom_cmd_keydb.o
endif
OBJS += ipcom_key_db.o
OBJS += ipcrypto_key_db_example_keys.o
endif
ifdef _WRS_CONFIG_SHELL
OBJS += secSecretCmd.o
OBJS += secVaultCmd.o
endif
DOC_FILES += secSecretLib.c
OBJS += secSecretLib.o
OBJS += secVaultKepObfuscator.o
ifdef _WRS_CONFIG_SEC_HASH
OBJS += secCipherXexAes.o
endif
OBJS += secKeyIvGenLib.o
endif # _WRS_ALL_DOCS
include $(WIND_KRNL_MK)/rules.library.mk
@@ -0,0 +1,642 @@
/*
* Copyright (c) 2006-2014, 2018-2021, 2023 Wind River Systems, Inc.
*
* The right to copy, distribute, modify or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
#include <ipcom_key_db.h>
#ifdef IPCOM_USE_KEY_DB
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#include <ipcom_type.h>
#include <ipcom_cstyle.h>
#include <ipcom_clib.h>
#include <ipcom_err.h>
#include <ipcom_sock.h>
#include <ipcom_shell.h>
#ifdef IPCRYPTO
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
#endif
#include <shellInterpCmdLib.h>
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
#define IPCOM_CMD_KEYDB_LIST 1
#define IPCOM_CMD_KEYDB_IMPORT 2
#define IPCOM_CMD_KEYDB_DELETE 3
#define IPCOM_CMD_KEYDB_PRINT 4
#define IPCOM_CMD_KEYDB_FIND 5
#define IPCOM_CMD_KEYDB_VERIFY 6
#define IPCOM_CMD_KEYDB_HELP 7
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
struct Ipcom_cmd_keydb_opt_st
{
const char* opt_name;
int id;
};
typedef struct Ipcom_cmd_keydb_opt_st Ipcom_cmd_keydb_opt;
/*
****************************************************************************
* 6 EXTERN PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 7 LOCAL PROTOTYPES
****************************************************************************
*/
IP_GLOBAL int ipcom_cmd_keydb(int argc, char** argv);
IP_STATIC int ipcom_cmd_keydb_delete(const char* type, const char* key_id);
LOCAL SHELL_CMD secKeyDBCmd =
{
"keydb",
ipcom_cmd_keydb,
NULL,
"keydb <command> [options]",
"keydb <command> [options]",
"Key DB admin command"
};
/*
****************************************************************************
* 8 DATA
****************************************************************************
*/
IP_STATIC Ipcom_cmd_keydb_opt keydb_opt_map[] =
{
{ "list", IPCOM_CMD_KEYDB_LIST },
{ "import", IPCOM_CMD_KEYDB_IMPORT },
{ "delete", IPCOM_CMD_KEYDB_DELETE },
{ "print", IPCOM_CMD_KEYDB_PRINT },
#ifdef IPCRYPTO
{ "find", IPCOM_CMD_KEYDB_FIND },
#endif
#ifdef IPCOM_USE_KEY_DB_CMD_VERIFY
{ "verify", IPCOM_CMD_KEYDB_VERIFY },
#endif
{ "help", IPCOM_CMD_KEYDB_HELP },
{ "-h", IPCOM_CMD_KEYDB_HELP },
{ NULL, 0 }
};
/*
****************************************************************************
* 9 STATIC FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipcom_cmd_keydb_usage
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC void
ipcom_cmd_keydb_usage(void)
{
(void)ipcom_printf("keydb [options]"IP_LF
" list <key|buf>"IP_LF
" import key key_id <key_file>"IP_LF
" import buf key_id buf"IP_LF
" delete <key|buf> <id>"IP_LF
" print <key_id>"IP_LF
" find <cert_file>"IP_LF
#ifdef IPCOM_USE_KEY_DB_CMD_VERIFY
" verify <buf_id>"IP_LF
#endif
" help|-h"IP_LF);
}
/*
*===========================================================================
* ipcom_cmd_keydb_import
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC int
ipcom_cmd_keydb_import(const char* type, const char* key_id, const char* extra)
{
int rc;
if (!type || !key_id)
return IPCOM_ERR_INVALID_ARG;
if (ipcom_strcmp(type, "key") == 0)
{
#if defined(IPCRYPTO) && !defined(OPENSSL_NO_STDIO)
EVP_PKEY* pkey;
FILE* fp;
const char* file = extra;
if (!file)
{
(void)ipcom_printf("File argument missing"IP_LF);
return IPCOM_ERR_INVALID_ARG;
}
fp = ipcom_fopen(file, "r");
if (!fp)
{
(void)ipcom_printf("Failed to open file: %s"IP_LF, file);
return IPCOM_ERR_INVALID_ARG;
}
pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL);
(void)ipcom_fclose(fp);
if (!pkey)
{
(void)ipcom_printf("Failed to read key from file: %s"IP_LF, file);
return IPCOM_ERR_FAILED;
}
rc = ipcom_key_db_pkey_import(key_id, pkey);
if (rc != IPCOM_SUCCESS)
(void)ipcom_printf("Failed: %s"IP_LF, ipcom_err_string(rc));
EVP_PKEY_free(pkey);
return rc;
#else
IPCOM_UNUSED_ARG(extra);
(void)ipcom_printf("Compiled out. Requires IPCRYPTO with STDIO support"IP_LF);
return IPCOM_ERR_NOT_SUPPORTED;
#endif /* IPCRYPTO */
}
if (ipcom_strcmp(type, "buf") == 0)
{
Ipcom_getline* gl = NULL;
char prompted_key[2][IPCOM_KEY_DB_MAX_BUF+4];
char* prompt[2] = {"Enter key:", "Re-type key:"};
int i;
gl = ipcom_getline_init(2);
if(!gl)
{
(void)ipcom_printf("Failed."IP_LF);
return IPCOM_ERR_FAILED;
}
for (i=0; i<2; i++)
{
(void)ipcom_printf(prompt[i]);
if(ipcom_getline(IP_INVALID_SOCKET, prompted_key[i], sizeof(prompted_key[i]), FALSE,
gl, (int)ipcom_strlen(prompt[i])))
{
(void)ipcom_printf("Failed"IP_LF);
(void)ipcom_getline_exit(gl);
return IPCOM_ERR_FAILED;
}
(void)ipcom_printf(IP_LF);
}
ipcom_getline_exit(gl);
if (ipcom_strcmp(prompted_key[0], prompted_key[1]) != 0)
{
(void)ipcom_printf("Failed. Entered keys do not match"IP_LF);
return IPCOM_ERR_FAILED;
}
rc = ipcom_key_db_buf_import(key_id, (UINT8*)prompted_key[0], (int)ipcom_strlen(prompted_key[0]));
if (rc != IPCOM_SUCCESS)
(void)ipcom_printf("Failed: %s"IP_LF, ipcom_err_string(rc));
return rc;
}
(void)ipcom_printf("Unknown import type: %s"IP_LF, type);
return IPCOM_ERR_INVALID_ARG;
}
/*
*===========================================================================
* ipcom_cmd_keydb_list
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC int
ipcom_cmd_keydb_list(const char* type)
{
void* handle;
char name[64];
if (ipcom_strcmp(type, "key") == 0)
{
#ifdef IPCRYPTO
handle = ipcom_key_db_pkey_opendb();
if (!handle)
{
(void)ipcom_printf("Failed to list key ids"IP_LF);
return IPCOM_ERR_FAILED;
}
while (1)
{
if (ipcom_key_db_pkey_readdb(handle, name, (int)sizeof(name)) == IPCOM_SUCCESS)
(void)ipcom_printf("%s"IP_LF, name);
else
{
(void)ipcom_key_db_pkey_closedb(handle);
return IPCOM_SUCCESS;
}
}
#else
(void)ipcom_printf("Compiled out. Requires IPCRYPTO"IP_LF);
return IPCOM_ERR_NOT_SUPPORTED;
#endif
}
if (ipcom_strcmp(type, "buf") == 0)
{
handle = ipcom_key_db_buf_opendb();
if (!handle)
{
(void)ipcom_printf("Failed to list buf ids"IP_LF);
return IPCOM_ERR_FAILED;
}
while (1)
{
if (ipcom_key_db_buf_readdb(handle, name, (int)sizeof(name)) == IPCOM_SUCCESS)
(void)ipcom_printf("%s"IP_LF, name);
else
{
(void)ipcom_key_db_buf_closedb(handle);
return IPCOM_SUCCESS;
}
}
}
(void)ipcom_printf("Unknown list type: %s"IP_LF, type);
return IPCOM_ERR_INVALID_ARG;
}
/*
*===========================================================================
* ipcom_cmd_keydb_delete
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC int
ipcom_cmd_keydb_delete(const char* type, const char* key_id)
{
if (ipcom_strcmp(type, "key") == 0)
{
#ifdef IPCRYPTO
if (ipcom_key_db_pkey_del(key_id))
{
(void)ipcom_printf("Failed"IP_LF);
return IPCOM_ERR_FAILED;
}
return IPCOM_SUCCESS;
#else
(void)ipcom_printf("Compiled out. Requires IPCRYPTO"IP_LF);
return IPCOM_ERR_NOT_SUPPORTED;
#endif
}
if (ipcom_strcmp(type, "buf") == 0)
{
if (ipcom_key_db_buf_del(key_id) != IPCOM_SUCCESS)
{
(void)ipcom_printf("Failed"IP_LF);
return IPCOM_ERR_FAILED;
}
return IPCOM_SUCCESS;
}
(void)ipcom_printf("Unknown type: %s"IP_LF, type);
return IPCOM_ERR_INVALID_ARG;
}
#if defined(IPCRYPTO) && !defined(IPCRYPTO_NO_STDIO)
/*
*===========================================================================
* ipcom_cmd_keydb_find
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC int
ipcom_cmd_keydb_find(const char* cert_file)
{
X509* x509 = NULL;
EVP_PKEY* pkey = NULL;
FILE* fp;
int rc = IPCOM_ERR_FAILED;
char key_id[64];
int key_id_len = (int)sizeof(key_id);
fp = ipcom_fopen(cert_file, "r");
if (!fp)
{
(void)ipcom_printf("Failed to open certificate file: %s"IP_LF, cert_file);
return IPCOM_ERR_INVALID_ARG;
}
x509 = PEM_read_X509(fp, NULL, NULL, NULL);
if (!x509)
{
(void)ipcom_printf("Failed to open certificate file: %s"IP_LF, cert_file);
goto cleanup;
}
pkey = ipcom_key_db_pkey_get2(x509, key_id, &key_id_len);
if (pkey)
{
(void)ipcom_printf("Key matching certificate found. key_id: %s"IP_LF, key_id);
rc = IPCOM_SUCCESS;
}
else
{
(void)ipcom_printf("No matching key found."IP_LF);
rc = IPCOM_ERR_NOT_FOUND;
}
cleanup:
if (fp)
(void)ipcom_fclose(fp);
if (x509)
X509_free(x509);
if (pkey)
EVP_PKEY_free(pkey);
return rc;
}
/*
*===========================================================================
* ipcom_cmd_keydb_print
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC int
ipcom_cmd_keydb_print(const char* key_id)
{
EVP_PKEY * pkey;
pkey = ipcom_key_db_pkey_get(key_id);
if (!pkey)
{
(void)ipcom_printf("Unknown key_id: %s"IP_LF, key_id);
return IPCOM_ERR_INVALID_ARG;
}
(void)EVP_PKEY_print_public_fp (ip_stdout, pkey,0, 0);
EVP_PKEY_free(pkey);
return 0;
}
#endif /* IPCRYPTO */
#ifdef IPCOM_USE_KEY_DB_CMD_VERIFY
/*
*===========================================================================
* ipcom_cmd_keydb_verify
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC Ip_err
ipcom_cmd_keydb_verify(const char* key_id)
{
char prompted_key[IPCOM_KEY_DB_MAX_BUF+1];
char stored_key[IPCOM_KEY_DB_MAX_BUF+1];
int key_len = sizeof(stored_key);
Ipcom_getline* gl = NULL;
Ip_err rc = IPCOM_ERR_FAILED;
gl = ipcom_getline_init(2);
if(!gl)
return IPCOM_ERR_FAILED;
(void)ipcom_printf("Enter key:");
if(ipcom_getline(IP_INVALID_SOCKET, prompted_key, sizeof(prompted_key), FALSE,
gl, (int)ipcom_strlen("Enter key:")))
{
(void)ipcom_printf("Failed"IP_LF);
goto cleanup;
}
(void)ipcom_printf(IP_LF);
if (ipcom_key_db_buf_get(key_id, (UINT8*)stored_key, &key_len) != IPCOM_SUCCESS)
{
(void)ipcom_printf("Failed to read key from db"IP_LF);
goto cleanup;
}
if ((int)ipcom_strlen(prompted_key) == key_len &&
ipcom_memcmp(stored_key, prompted_key, (size_t)key_len) == 0)
{
(void)ipcom_printf("Keys match"IP_LF);
}
else
(void)ipcom_printf("Keys do not match"IP_LF);
rc = IPCOM_SUCCESS;
cleanup:
if(gl)
ipcom_getline_exit(gl);
return rc;
}
#endif /* IPCOM_USE_KEY_DB_CMD_VERIFY */
/*
****************************************************************************
* 10 GLOBAL FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipcom_cmd_keydb
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_GLOBAL int
ipcom_cmd_keydb(int argc, char** argv)
{
int cmd_id = ~0;
int matches = 0;
int ret = 0;
Ipcom_cmd_keydb_opt* cmd_opt = keydb_opt_map;
if (argc < 2)
{
ipcom_cmd_keydb_usage();
return IPCOM_ERR_INVALID_ARG;
}
for (;cmd_opt->opt_name; cmd_opt++)
{
if (ipcom_strncmp(argv[1], cmd_opt->opt_name, ipcom_strlen(argv[1])) == 0)
{
cmd_id = cmd_opt->id;
matches++;
}
}
if (matches == 0)
{
(void)ipcom_printf("Unknown option: %s"IP_LF, argv[1]);
(void)ipcom_printf("%s -h gives usage info"IP_LF, argv[0]);
return IPCOM_ERR_INVALID_ARG;
}
if (matches > 1)
{
(void)ipcom_printf("Ambiguous option : %s"IP_LF, argv[1]);
(void)ipcom_printf("%s -h gives usage info"IP_LF, argv[0]);
return IPCOM_ERR_INVALID_ARG;
}
switch (cmd_id)
{
case IPCOM_CMD_KEYDB_LIST:
if (argc != 3)
{
ipcom_cmd_keydb_usage();
return IPCOM_ERR_INVALID_ARG;
}
return ipcom_cmd_keydb_list(argv[2]);
case IPCOM_CMD_KEYDB_IMPORT:
if (argc < 4 || argc > 5)
{
ipcom_cmd_keydb_usage();
return IPCOM_ERR_INVALID_ARG;
}
return ipcom_cmd_keydb_import(argv[2], argv[3], argv[4]);
case IPCOM_CMD_KEYDB_DELETE:
if (argc != 4)
{
ipcom_cmd_keydb_usage();
return IPCOM_ERR_INVALID_ARG;
}
return ipcom_cmd_keydb_delete(argv[2], argv[3]);
case IPCOM_CMD_KEYDB_PRINT:
if (argc != 3)
{
ipcom_cmd_keydb_usage();
return IPCOM_ERR_INVALID_ARG;
}
#if defined(IPCRYPTO) && !defined(IPCRYPTO_NO_STDIO)
return ipcom_cmd_keydb_print(argv[2]);
#else
ipcom_printf("Compiled out. Requires IPCRYPTO"IP_LF);
return IPCOM_ERR_NOT_SUPPORTED;
#endif
case IPCOM_CMD_KEYDB_FIND:
if (argc != 3)
{
ipcom_cmd_keydb_usage();
return IPCOM_ERR_INVALID_ARG;
}
#if defined(IPCRYPTO) && !defined(IPCRYPTO_NO_STDIO)
return ipcom_cmd_keydb_find(argv[2]);
#else
ipcom_printf("Compiled out. Requires IPCRYPTO"IP_LF);
return IPCOM_ERR_NOT_SUPPORTED;
#endif
case IPCOM_CMD_KEYDB_VERIFY:
if (argc != 3)
{
ipcom_cmd_keydb_usage();
return IPCOM_ERR_INVALID_ARG;
}
return ipcom_cmd_keydb_verify(argv[2]);
case IPCOM_CMD_KEYDB_HELP:
ipcom_cmd_keydb_usage();
return IPCOM_SUCCESS;
default:
ret = IPCOM_ERR_FAILED;
break;
}
return ret;
}
void ipcom_cmd_keydb_init(void)
{
(void)shellCmdTopicAdd ("keydb",
"List of the shell commands related to keydb.");
(void)shellCmdAdd("keydb", &secKeyDBCmd);
}
#else
int ipcom_cmd_keydb_empty_file;
#endif
/*
****************************************************************************
* 11 PUBLIC FUNCTIONS
****************************************************************************
*/
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
@@ -0,0 +1,479 @@
/*
* Copyright (c) 2014, 2017-2018, 2020-2021 Wind River Systems, Inc.
*
* The right to copy, distribute, modify or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
#include <ipcom_key_db.h>
#ifdef IPCOM_USE_KEY_DB
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#include <ipcom_type.h>
#include <ipcom_cstyle.h>
#include <ipcom_clib.h>
#include <ipcom_sysvar.h>
#include <ipcom_syslog.h>
#include <ipcom_err.h>
#include <ipcom_file.h>
#include <vxWorks.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <taskLib.h>
#include <sysLib.h>
#include <secSecret.h>
#include <secKeyStore.h>
#include <private/secSecretP.h>
#include <private/secKeyStoreP.h>
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
#ifndef IPCOM_KEY_DB_MAX_PATH
#define IPCOM_KEY_DB_MAX_PATH 128
#endif
#ifndef IPCOM_KEY_DB_MAX_SECRET
#define IPCOM_KEY_DB_MAX_SECRET 32
#endif
#define IPCOM_KEY_DB_TYPE_PKEY 1
#define IPCOM_KEY_DB_TYPE_BUF 2
#define IPCOM_KEY_DB_MODE_READ 1
#define IPCOM_KEY_DB_MODE_WRITE 2
#define IPCOM_SYSLOG_PRIORITY IPCOM_SYSLOG_IPCOM_PRIORITY
#define IPCOM_SYSLOG_FACILITY IPCOM_LOG_IPCOM_KEY_DB
#define MAX_BLOCK_SIZE 16
#ifdef EVP_MAX_KEY_LENGTH
#define IPCOM_KEY_DB_MAX_KEY_LENGTH EVP_MAX_KEY_LENGTH
#else
#define IPCOM_KEY_DB_MAX_KEY_LENGTH 32
#endif
#ifdef EVP_MAX_IV_LENGTH
#define IPCOM_KEY_DB_MAX_IV_LENGTH EVP_MAX_IV_LENGTH
#else
#define IPCOM_KEY_DB_MAX_IV_LENGTH 16
#endif
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
struct evp_pkey_st;
typedef struct evp_pkey_st EVP_PKEY;
/*
****************************************************************************
* 6 EXTERN PROTOTYPES
****************************************************************************
*/
extern void keydb_configure(void);
/*
****************************************************************************
* 7 LOCAL PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 8 DATA
****************************************************************************
*/
/*
****************************************************************************
* 9 STATIC FUNCTIONS
****************************************************************************
*/
/*
****************************************************************************
* 11 PUBLIC FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipcom_key_db_pkey_get
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_PUBLIC EVP_PKEY*
ipcom_key_db_pkey_get(const char* key_id)
{
if (!key_id || ipcom_strlen(key_id) > IPCOM_KEY_DB_MAX_ID)
return NULL;
return secKeyStoreGet(key_id);
}
/*
*===========================================================================
* ipcom_key_db_pkey_import
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_PUBLIC Ip_err
ipcom_key_db_pkey_import(const char* key_id, EVP_PKEY* key)
{
STATUS rc;
if (!key || !key_id || ipcom_strlen(key_id) > IPCOM_KEY_DB_MAX_ID)
return IPCOM_ERR_INVALID_ARG;
rc = secKeyStoreImport(key_id, key);
if (rc != OK)
switch (errno)
{
case EEXIST:
return IPCOM_ERR_ALREADY_INSTALLED;
default:
return IPCOM_ERR_FAILED;
}
return IPCOM_SUCCESS;
}
/*
*===========================================================================
* ipcom_key_db_pkey_get2
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_PUBLIC EVP_PKEY*
ipcom_key_db_pkey_get2(struct x509_st* x509, char* key_id, int* key_id_len)
{
return secKeyStoreX509Get(x509, key_id, key_id_len);
}
/*
*===========================================================================
* ipcom_key_db_pkey_opendb
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_PUBLIC void*
ipcom_key_db_pkey_opendb(void)
{
return secKeyStoreOpen();
}
/*
*===========================================================================
* ipcom_key_db_pkey_readdb
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_PUBLIC Ip_err
ipcom_key_db_pkey_readdb(void* handle, char* name, int name_len)
{
STATUS rc;
if (!handle || !name)
return IPCOM_ERR_INVALID_ARG;
rc = secKeyStoreRead(handle, name, name_len);
if (rc != OK)
switch (errno)
{
case EINVAL:
return IPCOM_ERR_INVALID_ARG;
default:
return IPCOM_ERR_END;
}
return IPCOM_SUCCESS;
}
/*
*===========================================================================
* ipcom_key_db_pkey_closedb
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_PUBLIC Ip_err
ipcom_key_db_pkey_closedb(void* handle)
{
if (secKeyStoreClose(handle) != OK)
return IPCOM_ERR_FAILED;
return IPCOM_SUCCESS;
}
/*
*===========================================================================
* ipcom_key_db_pkey_del
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_PUBLIC Ip_err
ipcom_key_db_pkey_del(const char* key_id)
{
STATUS rc;
rc = secKeyStoreDel(key_id);
if (rc != OK)
switch (errno)
{
case EINVAL:
return IPCOM_ERR_INVALID_ARG;
case ENOENT:
return IPCOM_ERR_NOT_FOUND;
default:
return IPCOM_ERR_FAILED;
}
return IPCOM_SUCCESS;
}
/*
*===========================================================================
* ipcom_key_db_buf_import
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_PUBLIC Ip_err
ipcom_key_db_buf_import(const char* key_id, const UINT8* key, int key_len)
{
STATUS status;
if (!key_id || ipcom_strlen(key_id) > IPCOM_KEY_DB_MAX_ID ||
!key ||
key_len > IPCOM_KEY_DB_MAX_BUF)
return IPCOM_ERR_INVALID_ARG;
status = secSecretImport(key_id, (const char*) key, key_len);
if (status != OK)
switch (errno)
{
case EEXIST:
return IPCOM_ERR_ALREADY_INSTALLED;
default:
return IPCOM_ERR_FAILED;
}
return IPCOM_SUCCESS;
}
/*
*===========================================================================
* ipcom_key_db_buf_get
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_PUBLIC Ip_err
ipcom_key_db_buf_get(const char* key_id, UINT8* buf, int* buf_len)
{
STATUS rc;
if (!key_id || ipcom_strlen(key_id) > IPCOM_KEY_DB_MAX_ID ||
!buf_len)
{
return IPCOM_ERR_INVALID_ARG;
}
rc = secSecretGet(key_id, (char*) buf, buf_len);
if (rc != OK)
switch (errno)
{
case ENOENT:
return IPCOM_ERR_NOT_FOUND;
default:
return IPCOM_ERR_FAILED;
}
return IPCOM_SUCCESS;
}
/*
*===========================================================================
* ipcom_key_db_buf_del
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_PUBLIC Ip_err
ipcom_key_db_buf_del(const char* key_id)
{
STATUS status;
if (!key_id || ipcom_strlen(key_id) > IPCOM_KEY_DB_MAX_ID)
{
return IPCOM_ERR_INVALID_ARG;
}
status = secSecretDel(key_id);
if (status != OK)
return IPCOM_ERR_FAILED;
return IPCOM_SUCCESS;
}
/*
*===========================================================================
* ipcom_key_db_buf_opendb
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_PUBLIC void*
ipcom_key_db_buf_opendb(void)
{
return secSecretOpen();
}
/*
*===========================================================================
* ipcom_key_db_buf_readdb
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_PUBLIC Ip_err
ipcom_key_db_buf_readdb(void* handle, char* name, int name_len)
{
STATUS rc;
rc = secSecretRead(handle, name, name_len);
if (rc != OK)
switch (errno)
{
case EINVAL:
return IPCOM_ERR_INVALID_ARG;
default:
return IPCOM_ERR_END;
}
return IPCOM_SUCCESS;
}
/*
*===========================================================================
* ipcom_key_db_buf_closedb
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_PUBLIC Ip_err
ipcom_key_db_buf_closedb(void* handle)
{
if (secSecretClose(handle) != OK)
return IPCOM_ERR_FAILED;
return IPCOM_SUCCESS;
}
/*
*===========================================================================
* ipcom_key_db_file_ready
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_GLOBAL void
ipcom_key_db_file_ready(void)
{
int i = 0;
while (secKeyStoreReadyCheck() != OK)
{
i++;
if (i >= 10)
{
break;
}
(void) taskDelay (sysClkRateGet()/10);
}
return;
}
#else
int ipcom_key_db_empty_file;
#endif
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
@@ -0,0 +1,515 @@
/* secCipher.c - VxWorks Symmetrical Encryption Library */
/*
* Copyright (c) 2015-2022 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
DESCRIPTION
This module is the VxWorks symmetrical encryption library. The library
separates the application using an encryption algorithm from the provider.
The application specifies what encryption algorithm to use by means of a
template. The template is used to initialize a cipher context. The API is
designed in such a way that once the cipher context is initialized, the
application does not need keep track of the encryption algorithm or mode used.
That is all encapsulated by the library.
 
Below is a code example encrypting two clear text buffers using Advanced Encryption
Standard (AES) and Cipher Block Chaining (CBC) with a 128 bit key:
\cs
SEC_CIPHER_CTX ctx;
unsigned char encrData[1024];
int encrLen = 0;
int outLen;
int tmpLen = sizeof(encrData);
secCipherInit(&ctx, vxCipherAes128CbcTemplateGet(), key, iv, 1);
secCipherUpdate(&ctx, encrData, &tmpLen, clearTextData, inLen);
encrLen = tmpLen;
outLen = sizeof(encrData)-encrLen;
secCipherUpdate(&ctx, encrData+encrLen, &outlen, clearTextData2, inLen2);
encrLen += outLen;
outLen = sizeof(encrData)-encrLen;
secCipherFinal(&ctx, encrData+encrLen, &outLen);
encrLen += outLen;
secCipherCleanup(&ctx);
/@ encrData now holds the encrypted data. encrLen holds the number of bytes
written to encrData @/
\ce
TEMPLATE FUNCTIONS
The following template functions exist:
\cs
const SEC_CIPHER_TEMPLATE* secCipherAes128CbcTemplateGet(void);
const SEC_CIPHER_TEMPLATE* secCipherAes128CtrTemplateGet(void);
const SEC_CIPHER_TEMPLATE* secCipherAes128EcbTemplateGet(void);
const SEC_CIPHER_TEMPLATE* secCipherAes192CbcTemplateGet(void);
const SEC_CIPHER_TEMPLATE* secCipherAes192CtrTemplateGet(void);
const SEC_CIPHER_TEMPLATE* secCipherAes256CbcTemplateGet(void);
const SEC_CIPHER_TEMPLATE* secCipherAes256CtrTemplateGet(void);
const SEC_CIPHER_TEMPLATE* secCipherAes256EcbTemplateGet(void);
const SEC_CIPHER_TEMPLATE* secCipherBlowfishCbcTemplateGet(void);
const SEC_CIPHER_TEMPLATE* secCipherCastCbcTemplateGet(void);
const SEC_CIPHER_TEMPLATE* secCipherDesCbcTemplateGet(void);
const SEC_CIPHER_TEMPLATE* secCipher3DesCbcTemplateGet(void);
const SEC_CIPHER_TEMPLATE* secCipherRc4TemplateGet(void);
\ce
A proprietary implementation of a hash algorithms can be installed by calling
set template function for that particular algorithm. The following set
template functions exist:
\cs
void secCipherAes128CbcTemplateSet(const SEC_CIPHER_TEMPLATE* ctx);
void secCipherAes128CtrTemplateSet(const SEC_CIPHER_TEMPLATE* ctx);
void secCipherAes128EcbTemplateSet(const SEC_CIPHER_TEMPLATE* ctx);
void secCipherAes192CbcTemplateSet(const SEC_CIPHER_TEMPLATE* ctx);
void secCipherAes192CtrTemplateSet(const SEC_CIPHER_TEMPLATE* ctx);
void secCipherAes256CbcTemplateSet(const SEC_CIPHER_TEMPLATE* ctx);
void secCipherAes256CtrTemplateSet(const SEC_CIPHER_TEMPLATE* ctx);
void secCipherAes256EcbTemplateSet(const SEC_CIPHER_TEMPLATE* ctx);
void secCipherAesCtrTemplateSet(const SEC_CIPHER_TEMPLATE* ctx);
void secCipherBlowfishCbcTemplateSet(const SEC_CIPHER_TEMPLATE* ctx);
void secCipherCastCbcTemplateSet(const SEC_CIPHER_TEMPLATE* ctx);
void secCipherDesCbcTemplateSet(const SEC_CIPHER_TEMPLATE* ctx);
void secCipher3DesCbcTemplateSet(const SEC_CIPHER_TEMPLATE* ctx);
void secCipherRc4TemplateSet(const SEC_CIPHER_TEMPLATE* ctx);
\ce
CONFIGURATION
The SECURITY_MISC_SEC_CRYPTO layer is included by default in the Source Build
Configuration.
The Kernel Configuration components for the cipher algorithms contain the prefix
INCLUDE_SEC_CIPHER_ followed by the description. For example, for an AES cipher
with CBC mode and a 128 bit key, the component is INCLUDE_SEC_CIPHER_AES_128_CBC
INCLUDE FILES: secCrypto.h
SEE ALSO
\tb [VxWorks Cryptography Libraries Programmer's Guide](https://docs.windriver.com/bundle/vxworks_cryptography_libraries_programmers_guide_@vx_release/page/sgr1441915476898.html)
*/
/* includes */
#include <secCrypto.h>
#include <string.h>
/*******************************************************************************
*
* secCipherInit - Initialize a cipher context
*
* This function initializes a cipher context. After the context has been initialized
* it can be used to encrypt/decrypt data using the secCipherUpdate function. The
* context will by default be setup for PKCS padding. See secCipherCtrl for how to
* disable PKCS padding.
* Note that a context that has been successfully initialized must be freed by calling
* secCipherCleanup.
*
* ARGUMENTS:
* \is
* \i ctx
* pointer to the context that will be initialized
* \i cipherTemplate
* template controlling what encryption algorithm to use, e.g. the return value of secCipherAes128CbcTemplateGet().
* \i key
* pointer to the encryption key. It is the responsibility of the caller to ensure that the key is sufficiently long.
* \i iv
* initialization vector, required by some algorithms/modes. It is the responsibility of the caller to ensure that the iv is sufficiently long.
* \i encr
* a non-zero value means that the context will be used for encryption, otherwise it will be setup for decryption.
* \ie
*
* RETURNS: OK if the context was successfully initialized, ERROR if it failed.
*
* ERRNO: N/A
*/
STATUS secCipherInit
(
SEC_CIPHER_CTX* ctx,
const SEC_CIPHER_TEMPLATE* cipherTemplate,
const unsigned char* key,
const unsigned char* iv,
const int encr
)
{
if (!ctx || !cipherTemplate || !cipherTemplate->cipherInit)
return ERROR;
memset(ctx, 0, sizeof(SEC_CIPHER_CTX));
ctx->cipher = cipherTemplate;
if (encr)
ctx->flags |= SEC_CIPHER_FLAG_ENCR;
ctx->flags |= SEC_CIPHER_FLAG_PKCS_PAD;
ctx->ctxData = NULL;
return cipherTemplate->cipherInit(ctx, key, iv, encr);
}
/*******************************************************************************
*
* secCipherUpdate - Encrypt or decrypt data
*
* This function encrypts or decrypts data. If data is to be encrypted or decrypted,
* and what encryption algorithm to use is specified in the initialization of ctx.
* see secCipherInit.
* Note that the number of bytes written to out can be both larger or smaller than
* inLen, when PKCS padding is enabled for block ciphers. At most, the output length
* can differ by one block from the input length.
* If a block cipher is used without padding, then the input length must be a multiple
* of the block size.
*
* ARGUMENTS:
* \is
* \i ctx
* pointer to the crypto context
* \i out
* pointer to buffer where the output will be stored
* \i outLen
* pointer to an integer where the output length will be stored
* \i in
* pointer to input data
* \i inLen
* number of input bytes
* \ie
*
* RETURNS: OK if the encryption/decryption was successful, ERROR otherwise
*
* ERRNO: N/A
*/
STATUS secCipherUpdate
(
SEC_CIPHER_CTX* ctx,
unsigned char* out,
int* outLen,
const unsigned char* in,
int inLen
)
{
int tmpOutLen = 0;
int tmpLen = 0;
unsigned char* orgOut = out;
STATUS rc = ERROR;
if ((ctx == NULL) || (ctx->cipher == NULL) ||
(ctx->cipher->cipherUpdate == NULL) || (out == NULL) ||
(outLen == NULL) || (in == NULL))
{
return ERROR;
}
if (inLen <= 0)
{
*outLen = 0;
return OK;
}
/* Check that output buffer is large enough */
if ((((inLen + (int) ctx->cachedBytes + (int) ctx->finalCachedBytes) / ctx->cipher->blockSize) *
ctx->cipher->blockSize) > *outLen)
{
*outLen = 0;
return ERROR;
}
/*
* Add a cached decrypted block to the output, before we start to process
* the input data in this call.
*/
if (((ctx->flags & SEC_CIPHER_FLAG_ENCR) == 0) &&
((ctx->flags & SEC_CIPHER_FLAG_PKCS_PAD) != 0) &&
(ctx->finalCachedBytes > 0))
{
memcpy(out, ctx->finalCache, ctx->finalCachedBytes);
out += ctx->finalCachedBytes;
tmpOutLen += (int) ctx->finalCachedBytes;
ctx->finalCachedBytes = 0;
}
if (ctx->cipher->blockSize > 1)
{
if (ctx->cachedBytes > 0)
{
/* Number of bytes missing in ctx->cache to create a full block */
int missing = ctx->cipher->blockSize - (int) ctx->cachedBytes;
if (inLen < missing)
{
memcpy(ctx->cache+ctx->cachedBytes, in, (size_t) inLen);
ctx->cachedBytes += (unsigned int) inLen;
*outLen = tmpOutLen;
return OK;
}
memcpy(ctx->cache+ctx->cachedBytes, in, (size_t) missing);
if (ctx->cipher->cipherUpdate(ctx, out, &tmpLen,
ctx->cache, ctx->cipher->blockSize) != OK)
{
*outLen = 0;
return ERROR;
}
inLen -= missing;
in += missing;
out += ctx->cipher->blockSize;
ctx->cachedBytes = 0;
tmpOutLen += tmpLen;
}
if (inLen % ctx->cipher->blockSize != 0)
{
ctx->cachedBytes = (unsigned int) (inLen % ctx->cipher->blockSize);
memcpy(ctx->cache, in + inLen - ctx->cachedBytes, ctx->cachedBytes);
inLen -= (int) ctx->cachedBytes;
}
if (inLen == 0)
{
rc = OK;
}
}
if (inLen > 0)
{
rc = ctx->cipher->cipherUpdate(ctx, out, outLen, in, inLen);
if (rc != OK)
{
*outLen = 0;
return ERROR;
}
tmpOutLen += *outLen;
}
/* Handle padding for decryption case */
if (ctx->cipher->blockSize > 1 &&
((ctx->flags & SEC_CIPHER_FLAG_ENCR) == 0) &&
((ctx->flags & SEC_CIPHER_FLAG_PKCS_PAD) != 0) &&
(ctx->cachedBytes == 0) && (tmpOutLen > 0))
{
memcpy(ctx->finalCache, orgOut+tmpOutLen-ctx->cipher->blockSize,
(size_t) ctx->cipher->blockSize);
tmpOutLen -= ctx->cipher->blockSize;
ctx->finalCachedBytes = (unsigned int) ctx->cipher->blockSize;
}
*outLen = tmpOutLen;
return rc;
}
/*******************************************************************************
*
* secCipherFinal - Finalize Encryption/Decryption
*
* This function finalizes an encryption/decryption operation consisting of a
* sequence of secCipherInit, secCipherUpdate, secCipherUpdate ..., secCipherFinal.
* The main reason why this function is needed, is to handle PKCS padding.
*
* ARGUMENTS:
* \is
* \i ctx
* pointer to the crypto context
* \i out
* pointer to buffer where the output will be stored
* \i outLen
* pointer to an integer where the output length will be stored
* \ie
*
* RETURNS: OK on success, ERROR otherwise
*
* ERRNO: N/A
*/
STATUS secCipherFinal
(
SEC_CIPHER_CTX* ctx,
unsigned char* out,
int* outLen
)
{
unsigned int i;
int paddedBytes;
if (!ctx || !ctx->cipher || !ctx->cipher->final || !out || !outLen)
return ERROR;
/* Check if a stream cipher is used */
if (ctx->cipher->blockSize == 1)
{
*outLen = 0;
return OK;
}
if((ctx->flags & SEC_CIPHER_FLAG_PKCS_PAD) == 0)
{
*outLen = 0;
if (ctx->cachedBytes == 0)
{
return OK;
}
else
{
/* Total input length is not a multiple of the block size */
return ERROR;
}
}
if ((ctx->flags & SEC_CIPHER_FLAG_ENCR) != 0)
{
paddedBytes = ctx->cipher->blockSize - (int) ctx->cachedBytes;
for (i=ctx->cachedBytes; i < (unsigned int)ctx->cipher->blockSize; i++)
ctx->cache[i] = (unsigned char)paddedBytes;
if (*outLen < ctx->cipher->blockSize)
{
*outLen = 0;
return ERROR;
}
return ctx->cipher->cipherUpdate(ctx, out, outLen, ctx->cache,
ctx->cipher->blockSize);
}
else
{
if (ctx->finalCachedBytes != (unsigned int) ctx->cipher->blockSize)
{
*outLen = 0;
return ERROR;
}
paddedBytes = ctx->finalCache[ctx->cipher->blockSize-1];
if (paddedBytes > ctx->cipher->blockSize)
{
*outLen = 0;
return ERROR;
}
memcpy(out, ctx->finalCache, (size_t) (ctx->cipher->blockSize-paddedBytes));
*outLen = ctx->cipher->blockSize-paddedBytes;
return OK;
}
}
/*******************************************************************************
*
* secCipherCtrl - Perform ioctl-like operations on a SEC_CIPHER_CTX
*
* This function is used to perform ioctl-like operations on a SEC_CIPHER_CTX.
* The following operations are defined:
* \is
* \i SEC_CIPHER_CTRL_SET_PADDING
* enable/disable PKCS padding.
* arg should of type int. 0 disables padding, a non-zero value enables padding.
* \i SEC_CIPHER_CTRL_GET_PADDING
* get PKCS padding setting.
* arg should be of type int*. The integer will be set to zero if padding is disabled, and one if padding is enabled.
* \i SEC_CIPHER_CTRL_GET_IV
* get a pointer to the initialization vector.
* arg should be of type unsigned char**
* \i SEC_CIPHER_CTRL_SET_IV
* set the initialization vector.
* arg should be of type unsigned char*
* \ie
*
* RETURNS: OK if the operation was successfully performed, ERROR otherwise
*
* ERRNO: N/A
*/
STATUS secCipherCtrl
(
SEC_CIPHER_CTX* ctx,
int type,
void* arg,
unsigned int* len
)
{
if (!ctx || !ctx->cipher || !ctx->cipher->ctrl)
return ERROR;
switch (type)
{
int padding;
int *pPad;
case SEC_CIPHER_CTRL_SET_PADDING:
padding = *((int*)arg);
if (padding)
{
ctx->flags |= SEC_CIPHER_FLAG_PKCS_PAD;
return OK;
}
else
{
ctx->flags &= (unsigned long ) (~SEC_CIPHER_FLAG_PKCS_PAD);
return OK;
}
case SEC_CIPHER_CTRL_GET_PADDING:
pPad = (int*)arg;
*pPad = (int)ctx->flags & SEC_CIPHER_FLAG_PKCS_PAD;
if (*pPad)
*pPad = 1;
else
*pPad = 0;
return OK;
}
return ctx->cipher->ctrl(ctx, type, arg, len);
}
/*******************************************************************************
*
* secCipherCleanup - Cleanup an initialized context
*
* This function cleans up an initialized context.
*
* RETURNS: OK if the operation was successfully performed, ERROR otherwise
*
* ERRNO: N/A
*/
STATUS secCipherCleanup
(
SEC_CIPHER_CTX* ctx
)
{
if (!ctx || !ctx->cipher || !ctx->cipher->cleanup)
return ERROR;
return ctx->cipher->cleanup(ctx);
}
/*******************************************************************************
*
* secCipherCopy - Copies a cipher context
*
* This function copies a cipher context. The state, e.g. working IV, is included in the copy.
*
* RETURNS: OK if the operation was successfully performed, ERROR otherwise
*
* ERRNO: N/A
*/
STATUS secCipherCopy
(
SEC_CIPHER_CTX* copy,
SEC_CIPHER_CTX* org
)
{
if (!copy || !org || !(org->cipher))
return ERROR;
if (!(org->cipher->copy))
{
memset(org, 0, sizeof(SEC_CIPHER_CTX));
return ERROR;
}
memcpy(copy, org, sizeof(SEC_CIPHER_CTX));
copy->ctxData = 0;
return org->cipher->copy(copy, org);
}
@@ -0,0 +1,70 @@
/* secCipher3DesCbc.c - SecCipher template functions for 3DES CBC */
/*
* Copyright (c) 2015, 2021 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
DESCRIPTION
SecCipher template functions for 3DES CBC
INCLUDE FILES: [secCrypto.h]
*/
/* includes */
#include <secCrypto.h>
#include <string.h>
/* locals */
static const SEC_CIPHER_TEMPLATE* trippleDesCbcTemplate = NULL;
/*******************************************************************************
*
* secCipher3DesCbcTemplateSet - Set the provider of the 3DES CBC encryption algorithm
*
* This function sets the provider of the 3DES CBC encryption algorithm. This function is
* typically called during boot to register a new implementation of the 3DES CBC algorithm.
* The provided template will be returned by secCipher3DesCbcTemplateGet.
*
* RETURNS: N/A
*
* ERRNO: N/A
*/
void secCipher3DesCbcTemplateSet
(
const SEC_CIPHER_TEMPLATE* template
)
{
if (template && template->type != SEC_CRYPTO_ID_3DES_CBC)
return;
trippleDesCbcTemplate = template;
}
/*******************************************************************************
*
* secCipher3DesCbcTemplateGet - Return the provider of the 3DES CBC encryption algorithm
*
* This function returns the template for the provider of the 3DES CBC encryption algorithm.
* The template is used in a call to secCipherInit to initialize an encryption/decryption
* context.
*
* RETURNS: The template for 3DES CBC encryption algorithm
*
* ERRNO: N/A
*/
const SEC_CIPHER_TEMPLATE* secCipher3DesCbcTemplateGet
(
void
)
{
return trippleDesCbcTemplate;
}
@@ -0,0 +1,70 @@
/* secCipherAes128Cbc.c - SecCipher template functions for AES 128 CBC */
/*
* Copyright (c) 2015, 2021 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
DESCRIPTION
SecCipher template functions for AES 128 CBC
INCLUDE FILES: [secCrypto.h]
*/
/* includes */
#include <secCrypto.h>
#include <string.h>
/* locals */
static const SEC_CIPHER_TEMPLATE* aes128CbcTemplate = NULL;
/*******************************************************************************
*
* secCipherAes128CbcTemplateSet - Set the provider of the AES 128 CBC encryption algorithm
*
* This function sets the provider of the AES 128 CBC encryption algorithm. This function is
* typically called during boot to register a new implementation of the AES 128 CBC algorithm.
* The provided template will be returned by secCipherAes128CbcTemplateGet.
*
* RETURNS: N/A
*
* ERRNO: N/A
*/
void secCipherAes128CbcTemplateSet
(
const SEC_CIPHER_TEMPLATE* template
)
{
if (template && template->type != SEC_CRYPTO_ID_AES_128_CBC)
return;
aes128CbcTemplate = template;
}
/*******************************************************************************
*
* secCipherAes128CbcTemplateGet - Return the provider of the AES 128 CBC encryption algorithm
*
* This function returns the template for the provider of the AES 128 CBC encryption algorithm.
* The template is used in a call to secCipherInit to initialize an encryption/decryption
* context.
*
* RETURNS: The template for AES 128 CBC encryption algorithm
*
* ERRNO: N/A
*/
const SEC_CIPHER_TEMPLATE* secCipherAes128CbcTemplateGet
(
void
)
{
return aes128CbcTemplate;
}
@@ -0,0 +1,79 @@
/* secCipherAes128Ctr.c - SecCipher template functions for AES 128 CTR */
/*
* Copyright (c) 2015, 2021 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
DESCRIPTION
SecCipher template functions for AES 128 CBC
INCLUDE FILES: [secCrypto.h]
*/
/* includes */
#include <secCrypto.h>
#include <string.h>
/* defines */
/* typedefs */
/* globals */
/* locals */
static const SEC_CIPHER_TEMPLATE* aes128ctrTemplate = NULL;
/* forward declarations */
/*******************************************************************************
*
* secCipherAes128CtrTemplateSet - Set the provider of the AES 128 CTR encryption algorithm
*
* This function sets the provider of the AES 128 CTR encryption algorithm. This function is
* typically called during boot to register a new implementation of the AES 128 CTR algorithm.
* The provided template will be returned by secCipherAes128CtrTemplateGet.
*
* RETURNS: N/A
*
* ERRNO: N/A
*/
void secCipherAes128CtrTemplateSet
(
const SEC_CIPHER_TEMPLATE* template
)
{
if (template && template->type != SEC_CRYPTO_ID_AES_128_CTR)
return;
aes128ctrTemplate = template;
}
/*******************************************************************************
*
* secCipherAes128CtrTemplateGet - Return the provider of the AES 128 CTR encryption algorithm
*
* This function returns the template for the provider of the AES 128 CTR encryption algorithm.
* The template is used in a call to secCipherInit to initialize an encryption/decryption
* context.
*
* RETURNS: The template for AES 128 CTR encryption algorithm
*
* ERRNO: N/A
*/
const SEC_CIPHER_TEMPLATE* secCipherAes128CtrTemplateGet
(
void
)
{
return aes128ctrTemplate;
}
@@ -0,0 +1,68 @@
/* secCipherAes128Ecb.c - SecCipher template functions for AES 128 ECB */
/*
* Copyright (c) 2015, 2021 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
DESCRIPTION
SecCipher template functions for AES 128 ECB
INCLUDE FILES: [secCrypto.h]
*/
/* includes */
#include <secCrypto.h>
#include <string.h>
/* locals */
static const SEC_CIPHER_TEMPLATE* aes128EcbTemplate = NULL;
/*******************************************************************************
*
* secCipherAes128EcbTemplateSet - Set the provider of the AES 128 ECB encryption algorithm
*
* This function sets the provider of the AES 128 ECB encryption algorithm. This function is
* typically called during boot to register a new implementation of the AES 128 ECB algorithm.
* The provided template will be returned by secCipherAes128EcbTemplateGet.
*
* RETURNS: N/A
*
* ERRNO: N/A
*/
void secCipherAes128EcbTemplateSet
(
const SEC_CIPHER_TEMPLATE* template
)
{
if (template && template->type != SEC_CRYPTO_ID_AES_128_ECB)
return;
aes128EcbTemplate = template;
}
/*******************************************************************************
*
* secCipherAes128EcbTemplateGet - Return the provider of the AES 128 ECB encryption algorithm
*
* This function returns the template for the provider of the AES 128 ECB encryption algorithm.
* The template is used in a call to secCipherInit to initialize an encryption/decryption
* context.
*
* RETURNS: The template for AES 128 ECB encryption algorithm
*
* ERRNO: N/A
*/
const SEC_CIPHER_TEMPLATE* secCipherAes128EcbTemplateGet(void)
{
return aes128EcbTemplate;
}
@@ -0,0 +1,70 @@
/* secCipherAes192Cbc.c - SecCipher template functions for AES 192 CBC */
/*
* Copyright (c) 2015, 2021 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
DESCRIPTION
SecCipher template functions for AES 192 CBC
INCLUDE FILES: [secCrypto.h]
*/
/* includes */
#include <secCrypto.h>
#include <string.h>
/* locals */
static const SEC_CIPHER_TEMPLATE* aes192CbcTemplate = NULL;
/*******************************************************************************
*
* secCipherAes192CbcTemplateSet - Set the provider of the AES 192 CBC encryption algorithm
*
* This function sets the provider of the AES 192 CBC encryption algorithm. This function is
* typically called during boot to register a new implementation of the AES 192 CBC algorithm.
* The provided template will be returned by secCipherAes192CbcTemplateGet.
*
* RETURNS: N/A
*
* ERRNO: N/A
*/
void secCipherAes192CbcTemplateSet
(
const SEC_CIPHER_TEMPLATE* template
)
{
if (template && template->type != SEC_CRYPTO_ID_AES_192_CBC)
return;
aes192CbcTemplate = template;
}
/*******************************************************************************
*
* secCipherAes192CbcTemplateGet - Return the provider of the AES 192 CBC encryption algorithm
*
* This function returns the template for the provider of the AES 192 CBC encryption algorithm.
* The template is used in a call to secCipherInit to initialize an encryption/decryption
* context.
*
* RETURNS: The template for AES 192 CBC encryption algorithm
*
* ERRNO: N/A
*/
const SEC_CIPHER_TEMPLATE* secCipherAes192CbcTemplateGet
(
void
)
{
return aes192CbcTemplate;
}
@@ -0,0 +1,70 @@
/* secCipherAes192Ctr.c - SecCipher template functions for AES 192 CTR */
/*
* Copyright (c) 2015, 2021 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
DESCRIPTION
SecCipher template functions for AES 192 CTR
INCLUDE FILES: [secCrypto.h]
*/
/* includes */
#include <secCrypto.h>
#include <string.h>
/* locals */
static const SEC_CIPHER_TEMPLATE* aes192ctrTemplate = NULL;
/*******************************************************************************
*
* secCipherAes192CtrTemplateSet - Set the provider of the AES 192 CTR encryption algorithm
*
* This function sets the provider of the AES 192 CTR encryption algorithm. This function is
* typically called during boot to register a new implementation of the AES 192 CTR algorithm.
* The provided template will be returned by secCipherAes192CtrTemplateGet.
*
* RETURNS: N/A
*
* ERRNO: N/A
*/
void secCipherAes192CtrTemplateSet
(
const SEC_CIPHER_TEMPLATE* template
)
{
if (template && template->type != SEC_CRYPTO_ID_AES_192_CTR)
return;
aes192ctrTemplate = template;
}
/*******************************************************************************
*
* secCipherAes192CtrTemplateGet - Return the provider of the AES 192 CTR encryption algorithm
*
* This function returns the template for the provider of the AES 192 CTR encryption algorithm.
* The template is used in a call to secCipherInit to initialize an encryption/decryption
* context.
*
* RETURNS: The template for AES 192 CTR encryption algorithm
*
* ERRNO: N/A
*/
const SEC_CIPHER_TEMPLATE* secCipherAes192CtrTemplateGet
(
void
)
{
return aes192ctrTemplate;
}
@@ -0,0 +1,69 @@
/* secCipherAes256Cbc.c - SecCipher template functions for AES 256 CBC */
/*
* Copyright (c) 2015, 2021 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
DESCRIPTION
SecCipher template functions for AES 256 CBC
INCLUDE FILES: [secCrypto.h]
*/
/* includes */
#include <secCrypto.h>
#include <string.h>
/* locals */
static const SEC_CIPHER_TEMPLATE* aes256CbcTemplate = NULL;
/*******************************************************************************
*
* secCipherAes256CbcTemplateSet - Set the provider of the AES 256 CBC encryption algorithm
*
* This function sets the provider of the AES 256 CBC encryption algorithm. This function is
* typically called during boot to register a new implementation of the AES 256 CBC algorithm.
* The provided template will be returned by secCipherAes256CbcTemplateGet.
*
* RETURNS: N/A
*
* ERRNO: N/A
*/
void secCipherAes256CbcTemplateSet
(
const SEC_CIPHER_TEMPLATE* template
)
{
if (template && template->type != SEC_CRYPTO_ID_AES_256_CBC)
return;
aes256CbcTemplate = template;
}
/*******************************************************************************
*
* secCipherAes256CbcTemplateGet - Return the provider of the AES 256 CBC encryption algorithm
*
* This function returns the template for the provider of the AES 256 CBC encryption algorithm.
* The template is used in a call to secCipherInit to initialize an encryption/decryption
* context.
*
* RETURNS: The template for AES 256 CBC encryption algorithm
*
* ERRNO: N/A
*/
const SEC_CIPHER_TEMPLATE* secCipherAes256CbcTemplateGet
(
void
)
{
return aes256CbcTemplate;
}
@@ -0,0 +1,69 @@
/* secCipherAes256Ctr.c - SecCipher template functions for AES 256 CTR */
/*
* Copyright (c) 2015, 2021 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
DESCRIPTION
SecCipher template functions for AES 256 CTR
INCLUDE FILES: [secCrypto.h]
*/
/* includes */
#include <secCrypto.h>
#include <string.h>
/* locals */
static const SEC_CIPHER_TEMPLATE* aes256ctrTemplate = NULL;
/*******************************************************************************
*
* secCipherAes256CtrTemplateSet - Set the provider of the AES 256 CTR encryption algorithm
*
* This function sets the provider of the AES 256 CTR encryption algorithm. This function is
* typically called during boot to register a new implementation of the AES 256 CTR algorithm.
* The provided template will be returned by secCipherAes256CtrTemplateGet.
*
* RETURNS: N/A
*
* ERRNO: N/A
*/
void secCipherAes256CtrTemplateSet
(
const SEC_CIPHER_TEMPLATE* template
)
{
if (template && template->type != SEC_CRYPTO_ID_AES_256_CTR)
return;
aes256ctrTemplate = template;
}
/*******************************************************************************
*
* secCipherAes256CtrTemplateGet - Return the provider of the AES 256 CTR encryption algorithm
*
* This function returns the template for the provider of the AES 256 CTR encryption algorithm.
* The template is used in a call to secCipherInit to initialize an encryption/decryption
* context.
*
* RETURNS: The template for AES 256 CTR encryption algorithm
*
* ERRNO: N/A
*/
const SEC_CIPHER_TEMPLATE* secCipherAes256CtrTemplateGet
(
void
)
{
return aes256ctrTemplate;
}
@@ -0,0 +1,68 @@
/* secCipherAes256Ecb.c - SecCipher template functions for AES 256 ECB */
/*
* Copyright (c) 2015, 2021 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
DESCRIPTION
SecCipher template functions for AES 256 ECB
INCLUDE FILES: [secCrypto.h]
*/
/* includes */
#include <secCrypto.h>
#include <string.h>
static const SEC_CIPHER_TEMPLATE* aes256EcbTemplate = NULL;
/*******************************************************************************
*
* secCipherAes256EcbTemplateSet - Set the provider of the AES 256 ECB encryption algorithm
*
* This function sets the provider of the AES 256 ECB encryption algorithm. This function is
* typically called during boot to register a new implementation of the AES 256 ECB algorithm.
* The provided template will be returned by secCipherAes256EcbTemplateGet.
*
* RETURNS: N/A
*
* ERRNO: N/A
*/
void secCipherAes256EcbTemplateSet
(
const SEC_CIPHER_TEMPLATE* template)
{
if (template && template->type != SEC_CRYPTO_ID_AES_256_ECB)
return;
aes256EcbTemplate = template;
}
/*******************************************************************************
*
* secCipherAes256EcbTemplateGet - Return the provider of the AES 256 ECB encryption algorithm
*
* This function returns the template for the provider of the AES 256 ECB encryption algorithm.
* The template is used in a call to secCipherInit to initialize an encryption/decryption
* context.
*
* RETURNS: The template for AES 256 ECB encryption algorithm
*
* ERRNO: N/A
*/
const SEC_CIPHER_TEMPLATE* secCipherAes256EcbTemplateGet
(
void
)
{
return aes256EcbTemplate;
}
@@ -0,0 +1,71 @@
/* secCipherBlowfishCbc.c - SecCipher template functions for Blowfish CBC */
/*
* Copyright (c) 2015, 2021 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
DESCRIPTION
SecCipher template functions for Blowfish CBC
INCLUDE FILES: [secCrypto.h]
*/
/* includes */
#include <secCrypto.h>
#include <string.h>
/* locals */
static const SEC_CIPHER_TEMPLATE* blowfishCbcTemplate = NULL;
/*******************************************************************************
*
* secCipherBlowfishCbcTemplateSet - Set the provider of the Blowfish CBC encryption algorithm
*
* This function sets the provider of the Blowfish CBC encryption algorithm. This function is
* typically called during boot to register a new implementation of the Blowfish CBC algorithm.
* The provided template will be returned by secCipherBlowfishCbcTemplateGet.
*
* RETURNS: N/A
*
* ERRNO: N/A
*/
void secCipherBlowfishCbcTemplateSet
(
const SEC_CIPHER_TEMPLATE* template
)
{
if (template && template->type != SEC_CRYPTO_ID_BF_CBC)
return;
blowfishCbcTemplate = template;
}
/*******************************************************************************
*
* secCipherBlowfishCbcTemplateGet - Return the provider of the Blowfish CBC encryption algorithm
*
* This function returns the template for the provider of the Blowfish CBC encryption algorithm.
* The template is used in a call to secCipherInit to initialize an encryption/decryption
* context.
*
* RETURNS: The template for Blowfish CBC encryption algorithm
*
* ERRNO: N/A
*/
const SEC_CIPHER_TEMPLATE* secCipherBlowfishCbcTemplateGet
(
void
)
{
return blowfishCbcTemplate;
}
@@ -0,0 +1,70 @@
/* secCipherCastCbc.c - SecCipher template functions for CAST CBC */
/*
* Copyright (c) 2015, 2021 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
DESCRIPTION
SecCipher template functions for CAST CBC
INCLUDE FILES: [secCrypto.h]
*/
/* includes */
#include <secCrypto.h>
#include <string.h>
/* locals */
static const SEC_CIPHER_TEMPLATE* castCbcTemplate = NULL;
/*******************************************************************************
*
* secCipherCastCbcTemplateSet - Set the provider of the CAST CBC encryption algorithm
*
* This function sets the provider of the CAST CBC encryption algorithm. This function is
* typically called during boot to register a new implementation of the CAST CBC algorithm.
* The provided template will be returned by secCipherCastCbcTemplateGet.
*
* RETURNS: N/A
*
* ERRNO: N/A
*/
void secCipherCastCbcTemplateSet
(
const SEC_CIPHER_TEMPLATE* template
)
{
if (template && template->type != SEC_CRYPTO_ID_CAST_CBC)
return;
castCbcTemplate = template;
}
/*******************************************************************************
*
* secCipherCastCbcTemplateGet - Return the provider of the CAST CBC encryption algorithm
*
* This function returns the template for the provider of the CAST CBC encryption algorithm.
* The template is used in a call to secCipherInit to initialize an encryption/decryption
* context.
*
* RETURNS: The template for CAST CBC encryption algorithm
*
* ERRNO: N/A
*/
const SEC_CIPHER_TEMPLATE* secCipherCastCbcTemplateGet
(
void
)
{
return castCbcTemplate;
}
@@ -0,0 +1,69 @@
/* secCipherDesCbc.c - SecCipher template functions for DES CBC */
/*
* Copyright (c) 2015, 2021 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
DESCRIPTION
SecCipher template functions for DES CBC
INCLUDE FILES: [secCrypto.h]
*/
/* includes */
#include <secCrypto.h>
#include <string.h>
/* locals */
static const SEC_CIPHER_TEMPLATE* desCbcTemplate = NULL;
/*******************************************************************************
*
* secCipherDesCbcTemplateSet - Set the provider of the DES CBC encryption algorithm
*
* This function sets the provider of the DES CBC encryption algorithm. This function is
* typically called during boot to register a new implementation of the DES CBC algorithm.
* The provided template will be returned by secCipherDesCbcTemplateGet.
*
* RETURNS: N/A
*
* ERRNO: N/A
*/
void secCipherDesCbcTemplateSet
(
const SEC_CIPHER_TEMPLATE* template
)
{
if (template && template->type != SEC_CRYPTO_ID_DES_CBC)
return;
desCbcTemplate = template;
}
/*******************************************************************************
*
* secCipherDesCbcTemplateGet - Return the provider of the DES CBC encryption algorithm
*
* This function returns the template for the provider of the DES CBC encryption algorithm.
* The template is used in a call to secCipherInit to initialize an encryption/decryption
* context.
*
* RETURNS: The template for DES CBC encryption algorithm
*
* ERRNO: N/A
*/
const SEC_CIPHER_TEMPLATE* secCipherDesCbcTemplateGet
(
void
)
{
return desCbcTemplate;
}
@@ -0,0 +1,69 @@
/* secCipherRc4.c - SecCipher template functions for RC4 */
/*
* Copyright (c) 2015, 2021 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
DESCRIPTION
SecCipher template functions for RC4
INCLUDE FILES: [secCrypto.h]
*/
/* includes */
#include <secCrypto.h>
#include <string.h>
/* locals */
static const SEC_CIPHER_TEMPLATE* rc4Template = NULL;
/*******************************************************************************
*
* secCipherRc4TemplateSet - Set the provider of the RC4 encryption algorithm
*
* This function sets the provider of the RC4 encryption algorithm. This function is
* typically called during boot to register a new implementation of the RC4 algorithm.
* The provided template will be returned by secCipherRc4TemplateGet.
*
* RETURNS: N/A
*
* ERRNO: N/A
*/
void secCipherRc4TemplateSet
(
const SEC_CIPHER_TEMPLATE* template
)
{
if (template && template->type != SEC_CRYPTO_ID_RC4)
return;
rc4Template = template;
}
/*******************************************************************************
*
* secCipherRc4TemplateGet - Return the provider of the RC4 encryption algorithm
*
* This function returns the template for the provider of the RC4 encryption algorithm.
* The template is used in a call to secCipherInit to initialize an encryption/decryption
* context.
*
* RETURNS: The template for RC4 encryption algorithm
*
* ERRNO: N/A
*/
const SEC_CIPHER_TEMPLATE* secCipherRc4TemplateGet
(
void
)
{
return rc4Template;
}
@@ -0,0 +1,383 @@
/* secCipherXexAes.c - XEX-AES Encryption Method Library */
/*
* Copyright (c) 2016, 2019, 2021-2022 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
DESCRIPTION
The file implements XEX-AES encryption method. It's normally used to encrypt a
storage device or block data aligned with 16 bytes. The implementation supports
AES ECB 128 or AES ECB 256. Users can choose one of them in VIP configuration.
The XEX-AES encryption method needs a master key to encrypt/decrypt. The master
key is protected by VxWorks Vault. Therefore, before using the component, users
need to configure VxWorks Vault correctly and import the correct key into
the vault.
*/
/* includes */
#include <secCrypto/secCipherXexAes.h>
/* defines */
#define GF_128_FDBK 135
/* forward declarations */
#if _BYTE_ORDER == _BIG_ENDIAN
LOCAL UINT64 secXexAesSwap64 (UINT64 val);
#endif /* _BYTE_ORDER == _BIG_ENDIAN */
/* functions */
#if _BYTE_ORDER == _BIG_ENDIAN
/*******************************************************************************
*
* secXexAesSwap64 - byte swap a 64 bit integer
*
* This routine performs an optimized endian swap of a 64 bit integer
* value.
*
* RETURNS: byte swapped 64 bit value
*
* ERRNO: N/A
*/
LOCAL UINT64 secXexAesSwap64
(
UINT64 val
)
{
return ((val >> 56) | ((val >> 40) & 0xFF00) |
((val >> 24) & 0xFF0000) | ((val >> 8) & 0xFF000000) |
((val << 8) & ((UINT64)0xFF << 32)) |
((val << 24) & ((UINT64)0xFF << 40)) |
((val << 40) & ((UINT64)0xFF << 48)) | ((val << 56)));
}
#endif /* _BYTE_ORDER == _BIG_ENDIAN */
/*******************************************************************************
*
* secXexAesInit - Initialize a cipher context
*
* This function initializes a cipher context. After the context has been
* initialized, it can be used to encrypt/decrypt data by using the
* secXexAesUpdate function.
*
* RETURNS: OK if the context was successfully initialized, ERROR if it failed.
*
* ERRNO: N/A
*
* \NOMANUAL
*/
STATUS secXexAesInit
(
SEC_XEX_AES_CTX * pCtx,
const SEC_CIPHER_TEMPLATE * pAesCipher,
UINT8 * key1,
UINT8 * key2,
size_t sectorSize
)
{
int pad = 0;
if ((pCtx == NULL) || (key1 == NULL) || (key2 == NULL) ||
(sectorSize <= 0) || ((sectorSize % SEC_CIPHER_AES_BLOCK_SIZE) != 0) ||
(pAesCipher == NULL) ||
((pAesCipher->type != SEC_CRYPTO_ID_AES_128_ECB) &&
(pAesCipher->type != SEC_CRYPTO_ID_AES_256_ECB)))
return ERROR;
pCtx->pSectorTweak = (UINT8 *)calloc (1, sectorSize);
if (pCtx->pSectorTweak == NULL)
return ERROR;
pCtx->sectorSize = sectorSize;
if (secCipherInit (&(pCtx->key1EncrCtx), pAesCipher, key1, NULL,
SEC_CIPHER_ENCR) != OK)
goto cleanup;
if (secCipherInit (&(pCtx->key1DecrCtx), pAesCipher, key1, NULL,
SEC_CIPHER_DECR) != OK)
goto cleanup;
if (secCipherInit (&(pCtx->key2EncrCtx), pAesCipher, key2, NULL,
SEC_CIPHER_ENCR) != OK)
goto cleanup;
if (secCipherCtrl (&(pCtx->key1EncrCtx), SEC_CIPHER_CTRL_SET_PADDING, &pad,
NULL) != OK)
goto cleanup;
if (secCipherCtrl (&(pCtx->key1DecrCtx), SEC_CIPHER_CTRL_SET_PADDING, &pad,
NULL) != OK)
goto cleanup;
if (secCipherCtrl (&(pCtx->key2EncrCtx), SEC_CIPHER_CTRL_SET_PADDING, &pad,
NULL) != OK)
goto cleanup;
return OK;
cleanup:
(void)secCipherCleanup (&(pCtx->key1EncrCtx));
(void)secCipherCleanup (&(pCtx->key1DecrCtx));
(void)secCipherCleanup (&(pCtx->key2EncrCtx));
free (pCtx->pSectorTweak);
pCtx->pSectorTweak = NULL;
return ERROR;
}
/*******************************************************************************
*
* secXexAesUpdate - Encrypt or decrypt data
*
* This function encrypts or decrypts data.
*
* RETURNS: OK if the encryption/decryption was successful, ERROR if it failed.
*
* ERRNO: N/A
*
* \NOMANUAL
*/
STATUS secXexAesUpdate
(
SEC_XEX_AES_CTX * pCtx,
unsigned char * out,
int * outLen,
const unsigned char * in,
int inLen,
long long sectorNum,
int encr
)
{
SEC_CIPHER_CTX * pAesCtx;
size_t sectors;
UINT64 * pTweak = NULL;
int aesOutLen;
UINT8 carryIn;
UINT8 carryOut;
int i;
int j;
if ((pCtx == NULL) || (out == NULL) || (outLen == NULL) || (in == NULL) ||
(inLen <= 0) || ((size_t) inLen % pCtx->sectorSize != 0) || (sectorNum < 0) ||
(*outLen < inLen) ||
(pCtx->pSectorTweak == NULL) ||
((encr != SEC_CIPHER_ENCR) && (encr != SEC_CIPHER_DECR)))
return ERROR;
pTweak = (UINT64 *)(pCtx->pSectorTweak);
sectors = (size_t) inLen / pCtx->sectorSize;
if (encr == SEC_CIPHER_ENCR)
pAesCtx = &(pCtx->key1EncrCtx);
else
pAesCtx = &(pCtx->key1DecrCtx);
while (sectors-- > 0)
{
*pTweak = (UINT64)(sectorNum++);
#if _BYTE_ORDER == _BIG_ENDIAN
*pTweak = secXexAesSwap64 (*pTweak);
#endif
*(pTweak + 1) = 0;
aesOutLen = SEC_CIPHER_AES_BLOCK_SIZE;
if (secCipherUpdate (&(pCtx->key2EncrCtx), pCtx->pSectorTweak,
&aesOutLen, pCtx->pSectorTweak,
SEC_CIPHER_AES_BLOCK_SIZE) != OK)
return ERROR;
for (i = SEC_CIPHER_AES_BLOCK_SIZE;
(size_t) i <= (pCtx->sectorSize - (size_t) SEC_CIPHER_AES_BLOCK_SIZE);
i += SEC_CIPHER_AES_BLOCK_SIZE)
{
for (carryIn = 0, j = 0; j < SEC_CIPHER_AES_BLOCK_SIZE; j++)
{
if ((*(pCtx->pSectorTweak + i + j - SEC_CIPHER_AES_BLOCK_SIZE) &
0x80) != 0)
carryOut = 1;
else
carryOut = 0;
*(pCtx->pSectorTweak + i + j) =
(UINT8)((*(pCtx->pSectorTweak + i + j -
SEC_CIPHER_AES_BLOCK_SIZE) << 1) + carryIn);
carryIn = carryOut;
}
if (carryOut == 1)
*(pCtx->pSectorTweak + i) ^= GF_128_FDBK;
}
for (i = 0; (size_t) i < pCtx->sectorSize; i++)
*(out + i) = *(in + i) ^ *((pCtx->pSectorTweak) + i);
aesOutLen = (int)(pCtx->sectorSize);
if (secCipherUpdate (pAesCtx, (UINT8 *)out, &aesOutLen, (UINT8 *)out,
(int)(pCtx->sectorSize)) != OK)
return ERROR;
for (i = 0; (size_t) i < pCtx->sectorSize; i++)
*(out + i) ^= *((pCtx->pSectorTweak) + i);
in += pCtx->sectorSize;
out += pCtx->sectorSize;
}
return OK;
}
/*******************************************************************************
*
* secXexAesCleanup - Clean up an initialized context
*
* This function cleans up an initialized context.
*
* RETURNS: OK if the operation was successfully performed, ERROR if it failed.
*
* ERRNO: N/A
*
* \NOMANUAL
*/
STATUS secXexAesCleanup
(
SEC_XEX_AES_CTX * pCtx
)
{
if (pCtx != NULL)
{
(void)secCipherCleanup (&(pCtx->key1EncrCtx));
(void)secCipherCleanup (&(pCtx->key1DecrCtx));
(void)secCipherCleanup (&(pCtx->key2EncrCtx));
if (pCtx->pSectorTweak != NULL)
free (pCtx->pSectorTweak);
bzero ((char *)pCtx, sizeof (SEC_XEX_AES_CTX));
}
else
return ERROR;
return OK;
}
#undef SEC_XEX_AES_DEBUG
#ifdef SEC_XEX_AES_DEBUG
/*******************************************************************************
*
* secXexAesLog - print the data in the buffer
*
* This function prints the data in the buffer.
*
* RETURNS: N/A
*
* ERRNO: N/A
*/
LOCAL void secXexAesLog
(
UINT8 * pBuf,
int size
)
{
int i;
for (i = 0; i < (size / sizeof (UINT8)); i++)
{
if ((i % 13) == 0)
printf ("\n");
printf ("0x%02x ", *pBuf++);
}
printf ("\n");
}
/*******************************************************************************
*
* secXexAesTest - Test XEX-AES encryption functionality
*
* This function tests the XEX-AES encryption functionality.
*
* RETURNS: OK if the test was passed, ERROR if it failed.
*
* ERRNO: N/A
*
* \NOMANUAL
*/
STATUS secXexAesTest
(
size_t sectorNum,
size_t sectorCnt
)
{
SEC_XEX_AES_CTX ctx;
UINT8 * pData = NULL;
UINT8 * pEncryptedData = NULL;
size_t sectorSize = 512;
int size = (int)(sectorSize * sectorCnt);
STATUS rc = ERROR;
int i;
int outLen;
UINT8 key1[SEC_CIPHER_MAX_BLOCK_SIZE];
UINT8 key2[SEC_CIPHER_MAX_BLOCK_SIZE];
memset ((char *)key1, 0x1, sizeof (key1));
memset ((char *)key2, 0x2, sizeof (key2));
if (secXexAesInit (&ctx, secCipherAes256EcbTemplateGet (), key1, key2,
sectorSize) != OK)
return rc;
pData = (UINT8 *)calloc (1, size);
if (pData == NULL)
goto cleanup;
pEncryptedData = (UINT8 *)calloc (1, size);
if (pEncryptedData == NULL)
goto cleanup;
for (i = 0; i < size; i++)
*(pData + i) = i;
outLen = size;
if (secXexAesUpdate (&ctx, pEncryptedData, &outLen, pData, size, sectorNum,
SEC_CIPHER_ENCR) != OK)
goto cleanup;
printf ("Cipher\n");
secXexAesLog (pEncryptedData, size);
bzero ((char *)pData, size);
outLen = size;
if (secXexAesUpdate (&ctx, pData, &outLen, pEncryptedData, size, sectorNum,
SEC_CIPHER_DECR) != OK)
goto cleanup;
printf ("Plaintext\n");
secXexAesLog (pData, size);
rc = OK;
cleanup:
(void)secXexAesCleanup (&ctx);
if (pData != NULL)
free (pData);
if (pEncryptedData != NULL)
free (pEncryptedData);
return rc;
}
#endif
@@ -0,0 +1,143 @@
/* secKeyIvGenLib.c - encryption key and initialization vector generation */
/*
* Copyright (c) 2017, 2021, 2025 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
DESCRIPTION
This module implements generating an encryption key and initialization
vector from a password.
...
INCLUDE FILES: [secHash.h ... | N/A]
*/
/* includes */
#include <vxWorks.h>
#include <string.h>
#include <secHash.h>
/* defines */
/* typedefs */
/* globals */
/* locals */
/* forward declarations */
/*******************************************************************************
*
* secKeyIvGen - generate key and iv
*
* This function generates a key and iv from a password.
*
* RETURNS: OK if successfully, otherwise ERROR.
*
* ERRNO: N/A
*/
STATUS secKeyIvGen
(
const char* pw,
const size_t pwLen,
unsigned char * key,
int keyLen,
unsigned char * iv,
int ivLen,
const SEC_HASH_TEMPLATE* hashTemplate
)
{
unsigned char mdBuf[20];
unsigned int mdLen;
int addmd=0;
unsigned int mds=20;
unsigned int i;
SEC_HASH_CTX ctx;
for (;;)
{
if (secHashInit (&ctx, hashTemplate) != OK)
{
return ERROR;
}
if (addmd++)
{
(void)secHashUpdate (&ctx,&(mdBuf[0]),mds);
}
(void)secHashUpdate (&ctx,pw,strlen (pw));
mdLen = sizeof (mdBuf);
(void)secHashFinal (&ctx, mdBuf,&mdLen);
(void)secHashCleanup (&ctx);
i = 0;
mds = 20;
if (keyLen != 0)
{
for (;;)
{
if (keyLen == 0)
{
break;
}
if (i == mds)
{
break;
}
if (key != NULL)
{
*(key++) = mdBuf[i];
}
keyLen--;
i++;
}
}
if ((ivLen != 0) && (i != mds))
{
for (;;)
{
if (ivLen == 0)
{
break;
}
if (i == mds)
{
break;
}
if (iv != NULL)
{
*(iv++) = mdBuf[i];
}
ivLen--;
i++;
}
}
if ((keyLen == 0) && (ivLen == 0))
{
break;
}
}
(void)memset (mdBuf, 0, sizeof (mdBuf));
return OK;
}
@@ -0,0 +1,417 @@
/* secKeyStoreCmd.c - Key store shell command */
/*
* Copyright (c) 2015, 2017, 2019-2021 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
DESCRIPTION
This module is an example of the Wind River Systems C coding conventions.
...
INCLUDE FILES: [N/A]
*/
/* includes */
#include <vxWorks.h>
#include <stdio.h>
#include <string.h>
#include <ioLib.h>
#include <shellInterpCmdLib.h>
#include <secKeyStore.h>
#include <private/secSecretP.h>
#include <private/secKeyStoreP.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
#if !defined (OPENSSL_NO_ENGINE) && defined (_WRS_CONFIG_TPM2_TSS)
#include <tpm2-tss-engine.h>
#endif /* !OPENSSL_NO_ENGINE && _WRS_CONFIG_TPM2_TSS */
/* defines */
/* typedefs */
/* globals */
/* locals */
/* forward declarations */
int secKeyStoreCmd(int argc, char** argv);
SHELL_CMD secKeyStoreCmdData =
{
"keyStore",
secKeyStoreCmd,
NULL,
"shell command to manage key pairs in the vault",
"shell command to manage key pairs in the vault",
"shell command to manage key pairs in the vault"
};
/*******************************************************************************
*
* secKeyStoreCmdInit - Initialization routine of INCLUDE_SEC_KEY_STORE_CMD
*
* RETURNS: N/A
*
* ERRNO: N/A
*/
void secKeyStoreCmdInit
(
void
)
{
(void)shellCmdTopicAdd ("security",
"List of the shell commands related to security.");
(void)shellCmdAdd("security", &secKeyStoreCmdData);
}
/*******************************************************************************
*
* secKeyStoreCmdUsage - keyStore shell command usage
*
* RETURNS: N/A
*
* ERRNO: N/A
*/
void secKeyStoreCmdUsage (void)
{
(void)printf ("keystore [options]\n"
" list \n"
" import <id> <file> <key-type> - imports the <key-type> specific key in <file> and gives it id <id>\n"
" <key-type> could be 'tpm2' or 'pkey'. If it is not specified, using 'pkey' by default\n"
" delete <id> - deletes <id> from the key store\n"
" print <id> - prints the public key of <id>\n"
" find <cert file> - prints the id of the key matching the cert in <cert file>\n"
" help|-h\n");
}
/*******************************************************************************
*
* secKeyStoreCmdImport - Import sub command of keyStore shell command
*
* RETURNS: OK if successful, ERROR otherwise
*
*/
int secKeyStoreCmdImport
(
int argc,
char ** argv
)
{
int rc = ERROR;
EVP_PKEY * pkey = NULL;
FILE * fp = NULL;
char * keyFile;
char * id;
char * keyTypeStr = NULL;
if ((argc != 2) && (argc != 3))
{
secKeyStoreCmdUsage ();
return ERROR;
}
id = argv[0];
keyFile = argv[1];
if (argc == 3)
keyTypeStr = argv[2];
#if !defined (OPENSSL_NO_ENGINE) && defined (_WRS_CONFIG_TPM2_TSS)
if ((keyTypeStr != NULL) && (strcmp (keyTypeStr, "tpm2") == 0))
{
ENGINE * tpmEngine;
tpmEngine = ENGINE_by_id ("tpm2tss");
if (tpmEngine == NULL)
{
printf ("Failed to load tpm2tss engine\n");
goto exit;
}
if (ENGINE_init (tpmEngine))
{
pkey = ENGINE_load_private_key (tpmEngine, keyFile, NULL, NULL);
if (pkey == NULL)
{
ENGINE_finish (tpmEngine);
}
}
else
{
printf ("Failed to initialize tpm2tss engine\n");
goto exit;
}
}
#endif /* !OPENSSL_NO_ENGINE && _WRS_CONFIG_TPM2_TSS */
if ((keyTypeStr == NULL) || (strcmp (keyTypeStr, "pkey") == 0))
{
fp = fopen (keyFile, "r");
if (!fp)
{
printf ("Unable to open file: %s\n", keyFile);
return ERROR;
}
pkey = PEM_read_PrivateKey (fp, NULL, NULL, NULL);
}
if (!pkey)
{
printf ("Failed to read private key\n");
goto exit;
}
rc = secKeyStoreImport (id, pkey);
if (rc != OK)
printf ("Failed to import key\n");
exit:
if (fp)
(void) fclose (fp);
if (pkey)
EVP_PKEY_free (pkey);
return rc;
}
/*******************************************************************************
*
* secKeyStoreCmdDelete - Delete sub command of keyStore shell command
*
* RETURNS: OK if successful, ERROR otherwise
*/
int secKeyStoreCmdDelete
(
int argc,
char** argv
)
{
char* id;
if (argc != 1)
{
secKeyStoreCmdUsage();
return ERROR;
}
id = argv[0];
return secKeyStoreDel(id);
}
/*******************************************************************************
*
* secKeyStoreCmdPrint - Print sub command of keyStore shell command
*
* RETURNS: OK if successful, ERROR otherwise
*/
int secKeyStoreCmdPrint
(
int argc,
char** argv
)
{
char* id;
EVP_PKEY *pkey;
BIO* out = NULL;
if (argc != 1)
{
secKeyStoreCmdUsage();
return ERROR;
}
id = argv[0];
pkey = secKeyStoreGet(id);
if (!pkey)
{
(void)printf("Unknown key id: %s\n", id);
return ERROR;
}
out = BIO_new_fp (stdout, BIO_NOCLOSE);
if (!out)
{
EVP_PKEY_free(pkey);
return ERROR;
}
(void)EVP_PKEY_print_public(out, pkey, 0, NULL);
EVP_PKEY_free(pkey);
(void)BIO_free(out);
return 0;
}
/*******************************************************************************
*
* secKeyStoreCmdList - List sub command of keyStore shell command
*
* RETURNS: OK if successful, ERROR otherwise
*/
int secKeyStoreCmdList
(
int argc,
char** argv
)
{
char name[SEC_SECRET_KEY_ID_MAX];
void* handle;
(void)argc;
(void)argv;
handle = secKeyStoreOpen();
if (!handle)
return ERROR;
while (1)
{
if (secKeyStoreRead(handle, name, sizeof(name)) != OK)
{
(void)secKeyStoreClose(handle);
return OK;
}
printf("%s\n", name);
}
return OK;
}
/*******************************************************************************
*
* secKeyStoreCmdFind - Find sub command of keyStore shell command
*
* RETURNS: OK if successful, ERROR otherwise
*/
int secKeyStoreCmdFind
(
int argc,
char** argv
)
{
X509* x509 = NULL;
EVP_PKEY* pkey = NULL;
FILE* fp;
int rc = ERROR;
char id[SEC_SECRET_KEY_ID_MAX];
int len = (int)sizeof(id);
char* certFile;
if (argc != 1)
{
secKeyStoreCmdUsage();
return ERROR;
}
certFile = argv[0];
fp = fopen(certFile, "r");
if (!fp)
{
printf("Failed to open certificate file: %s\n", certFile);
return ERROR;
}
x509 = PEM_read_X509(fp, NULL, NULL, NULL);
if (!x509)
{
(void)printf("Failed to open certificate file: %s\n", certFile);
goto cleanup;
}
pkey = secKeyStoreX509Get(x509, id, &len);
if (pkey)
{
(void)printf("Key matching certificate found. id: %s\n", id);
rc = OK;
}
else
{
(void)printf("No matching key found.\n");
}
cleanup:
if (fp)
(void)fclose(fp);
if (x509)
X509_free(x509);
if (pkey)
EVP_PKEY_free(pkey);
return rc;
}
/*******************************************************************************
*
* secKeyStoreCmd - keyStore shell command
*
* See secKeyStoreCmdUsage for a usage description of the command
*
* RETURNS: OK if successful, ERROR otherwise
*/
int secKeyStoreCmd
(
int argc,
char** argv
)
{
const char* cmd;
if (argc < 2)
{
secKeyStoreCmdUsage();
return ERROR;
}
cmd = argv[1];
argc -= 2;
argv += 2;
if (strcmp(cmd, "import") == 0)
{
return secKeyStoreCmdImport(argc, argv);
}
if (strcmp(cmd, "delete") == 0)
{
return secKeyStoreCmdDelete(argc, argv);
}
if (strcmp(cmd, "print") == 0)
{
return secKeyStoreCmdPrint(argc, argv);
}
if (strcmp(cmd, "list") == 0)
{
return secKeyStoreCmdList(argc, argv);
}
if (strcmp(cmd, "find") == 0)
{
return secKeyStoreCmdFind(argc, argv);
}
if ((strcmp(cmd, "help") == 0) || (strcmp(cmd, "-h") == 0))
{
secKeyStoreCmdUsage();
return OK;
}
printf("keyStore: unknown sub-command: %s\n", cmd);
secKeyStoreCmdUsage();
return ERROR;
}
@@ -0,0 +1,494 @@
/* secKeyStoreLib.c - VxWorks Key Store */
/*
* Copyright (c) 2015, 2017, 2019-2022 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
DESCRIPTION
The key store is used to store public key pairs, key pairs used in SSL connections.
e.g. A typical usage would be an application that listens to incoming SSL connections.
This application then needs to have an X509 certificate and a matching private/public
key pair. The X509 certification does not need to be protected against unauthorized reading.
It can simply be stored in the file system. The key pair, however, is sensitive and
should be stored in the key store.
First, the key pair must be imported into the key store. This is typically done by
a system administrator, e.g. by using the keystore shell command. The system administrator
either generates a key pair on the target, or transfers a key pair to the target.
Assuming the key is in the file ‘mySslKey.pem’. The sysadmin then issues the following command:
keyStore import mySslKey mySslKey.pem
Now the key pair in mySslKey.pem have been imported into the key store and given the id
‘mySslKey’. The sysadmin now deletes mySslKey.pem from the file system. In runtime the
application fetches the SSL key from the key store in the following way:
\cs
EVP_PKEY* sslKey;
sslKey = keyStoreGet(“mySslKey”);
if (!sslKey)
{
/@ error handling @/
}
/@ use the sslKey as appropriate for your application @/
/@ Once done with the key, free it @/
EVP_PKEY_free(sslKey);
\ce
The key pairs are stored encrypted in files. A passwords is used to generate the encryption key.
The password is called a key-encrypting password. A handler must be configured by means of the
SELECT_SEC_SECRET_KEPW_HANDLER CDF selection. Note that the key-encrypting password from the
VxWorks Vault is used for the Key Store as well.
CONFIGURATION
The SECURITY_MISC_SEC_CRYPTO layer is included by default in the Source Build
Configuration.
Add the INCLUDE_SEC_KEY_STORE component to your Kernel Configuration (Note that you will get
a configuration error, because it adds INCLUDE_SEC_VAULT_KEP_OBFUSCATOR and its parameter
SEC_VAULT_KEY_ENCRYPTING_PW must be set.). To use key store management commands, add
the INCLUDE_SEC_KEY_STORE_CMD component.
INCLUDE FILES: secKeyStore.h
SEE ALSO
\tb [VxWorks Security Programmer's Guide](https://docs.windriver.com/bundle/vxworks_security_programmers_guide_@vx_release/page/sgr1441915476898.html),
\tb [VxWorks Cryptography Libraries Programmer's Guide](https://docs.windriver.com/bundle/vxworks_cryptography_libraries_programmers_guide_@vx_release/page/ryo1495571729223.html)
*/
/* includes */
#include <vxWorks.h>
#include <semLib.h>
#include <stdio.h>
#include <string.h>
#include <dirent.h>
#include <ioLib.h>
#include <usrFsLib.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#if !defined (OPENSSL_NO_ENGINE) && defined (_WRS_CONFIG_TPM2_TSS)
#include <tpm2-tss-engine.h>
#endif /* !OPENSSL_NO_ENGINE && _WRS_CONFIG_TPM2_TSS */
#include <private/secSecretP.h>
#include <private/secKeyStoreP.h>
#include <iosLib.h>
/* defines */
/* typedefs */
/* globals */
/* locals */
void* secKeyStoreOpen(void);
STATUS secKeyStoreRead(void* handle, char* keyId, int len);
ENGINE * EVP_PKEY_engine(const EVP_PKEY *pkey);
/* forward declarations */
/* Dummy CDF init routine */
void secKeyStoreInit(void)
{
}
int secKeyStoreKepGet(char *buf, int size, int rwflag, void *userdata)
{
(void)rwflag;
(void)userdata;
if (secSecretKepGet(buf, &size) != OK)
return 0;
else
return size;
}
/*******************************************************************************
*
* secKeyStoreGet - Get a key pair from the key store
*
* Fetches a key pair from the key store.
*
* RETURNS: Pointer to the key pair with the specified key id, or NULL if no such
* key id exist or if an error occurred.
*
* ERRNO:
* \is
* \i ENOENT
* The key id does not exist
* \i EINVAL
* Invalid arguments
* \i ENODEV
* The TPM2 OpenSSL engine does not exist.
* \ie
*/
EVP_PKEY* secKeyStoreGet
(
const char * keyId
)
{
FILE * fp = NULL;
EVP_PKEY * ret = NULL;
if (!keyId || strlen (keyId) > SEC_SECRET_KEY_ID_MAX)
{
errno = EINVAL;
return NULL;
}
secSecretLock ();
/* Check if the key id already exist */
#if !defined (OPENSSL_NO_ENGINE) && defined (_WRS_CONFIG_TPM2_TSS)
fp = secSecretFpGet (keyId, SEC_SECRET_TYPE_TPM2_KEY, SEC_SECRET_MODE_READ);
if (fp)
{
ENGINE * tpmEngine;
char filePath[SEC_SECRET_PATH_MAX];
tpmEngine = ENGINE_by_id ("tpm2tss");
if (tpmEngine == NULL)
{
errno = ENODEV;
goto leave;
}
if (ENGINE_init (tpmEngine))
{
(void) fclose (fp);
fp = NULL;
if (secSecretGetFilePath (keyId, SEC_SECRET_TYPE_TPM2_KEY, filePath,
sizeof (filePath)) != OK)
{
ENGINE_finish (tpmEngine);
goto leave;
}
ret = ENGINE_load_private_key (tpmEngine, filePath, NULL, NULL);
if (ret == NULL)
{
ENGINE_finish (tpmEngine);
goto leave;
}
}
else
{
errno = ENODEV;
goto leave;
}
}
else
#endif /* !OPENSSL_NO_ENGINE && _WRS_CONFIG_TPM2_TSS */
{
fp = secSecretFpGet (keyId, SEC_SECRET_TYPE_PKEY, SEC_SECRET_MODE_READ);
if (!fp)
goto leave;
ret = PEM_read_PrivateKey (fp, NULL, secKeyStoreKepGet, NULL);
}
leave:
if (fp)
(void) fclose (fp);
secSecretUnlock ();
return ret;
}
/*******************************************************************************
*
* secKeyStoreImport - import a key pair into the key store
*
* This function imports a key pair into the key store and assigns keyId as the
* key id.
*
* RETURNS: OK on success, ERROR if the key pair could not be imported
*
* ERRNO:
* \is
* \i EEXISTS
* There is an existing key in the key store with the same key id.
* \i EINVAL
* Invalid arguments
* \ie
*/
int secKeyStoreImport
(
const char * keyId,
EVP_PKEY * key
)
{
FILE * fp;
int rc = ERROR;
if (!keyId || strlen (keyId) > SEC_SECRET_KEY_ID_MAX || !key)
{
errno = EINVAL;
return ERROR;
}
secSecretLock ();
/* Check if the key id already exist */
fp = secSecretFpGet (keyId, SEC_SECRET_TYPE_PKEY, SEC_SECRET_MODE_READ);
if (fp)
{
errno = EEXIST;
goto leave;
}
#if !defined (OPENSSL_NO_ENGINE) && defined (_WRS_CONFIG_TPM2_TSS)
fp = secSecretFpGet (keyId, SEC_SECRET_TYPE_TPM2_KEY, SEC_SECRET_MODE_READ);
if (fp)
{
errno = EEXIST;
goto leave;
}
if ((EVP_PKEY_engine(key) != NULL) &&
(ENGINE_get_id (EVP_PKEY_engine(key)) != NULL) &&
(strcmp (ENGINE_get_id (EVP_PKEY_engine(key)), "tpm2tss") == 0))
{
TPM2_DATA * tpm2Data = NULL;
char filePath[SEC_SECRET_PATH_MAX];
if (secSecretGetFilePath (keyId, SEC_SECRET_TYPE_TPM2_KEY, filePath,
sizeof (filePath)) != OK)
{
goto leave;
}
if ((EVP_PKEY_get0_RSA(key) != NULL) &&
(RSA_get_method(EVP_PKEY_get0_RSA(key)) != NULL) &&
(RSA_meth_get0_name(RSA_get_method(EVP_PKEY_get0_RSA(key))) != NULL) &&
(strcmp (RSA_meth_get0_name(RSA_get_method(EVP_PKEY_get0_RSA(key))), "TPM2TSS RSA methods") == 0))
{
tpm2Data = RSA_get_app_data (EVP_PKEY_get0_RSA(key));
}
else if (EVP_PKEY_get0_EC_KEY(key) != NULL)
{
tpm2Data = tpm2tss_ecc_getappdata ((EC_KEY *)EVP_PKEY_get0_EC_KEY(key));
}
if (tpm2Data != NULL)
{
if (tpm2tss_tpm2data_write (tpm2Data, filePath))
{
rc = OK;
}
}
}
else
#endif /* !OPENSSL_NO_ENGINE && _WRS_CONFIG_TPM2_TSS */
{
/* Reopen file in write mode */
fp = secSecretFpGet (keyId, SEC_SECRET_TYPE_PKEY, SEC_SECRET_MODE_WRITE);
if (!fp)
goto leave;
if (!PEM_write_PKCS8PrivateKey (fp, (EVP_PKEY*)key, EVP_aes_256_cbc (),
NULL, 0, secKeyStoreKepGet, NULL))
goto leave;
}
rc = OK;
leave:
if (fp)
(void) fclose (fp);
secSecretUnlock ();
return rc;
}
/*******************************************************************************
*
* secKeyStoreX509Get - Get a key pair matching a X509 certificate
*
* Get a key pair matching a X509 certificate. The x509 argument must be set,
* keyId and keyIdLen are optional and can be set to NULL. If keyId and keyIdLen
* are set they will be updated with the key id of key pair matching the x509
* certificate.
*
* RETURNS: Pointer to the key pair matching a X509 certificate, or NULL in case of error
*
* ERRNO:
* \is
* \i EINVAL
* Invalid arguments
* \i ENOENT
* No key pair matching the X509 certificate found.
* \ie
*/
EVP_PKEY* secKeyStoreX509Get
(
X509* x509,
char* keyId,
int* keyIdLen
)
{
EVP_PKEY* pkey = NULL;
char intKeyId[SEC_SECRET_PATH_MAX] = {0};
EVP_PKEY* certPubKey = NULL;
void* handle = NULL;
/* x509 argument must be given. keyId and keyIdLen are optional, but if keyId is provided.
* keyIdLen must be provided too. */
if (!x509 || (keyId && !keyIdLen))
{
errno = EINVAL;
return NULL;
}
certPubKey = X509_get_pubkey(x509);
if (!certPubKey)
return NULL;
secSecretLock();
handle = secKeyStoreOpen();
while (handle)
{
if (secKeyStoreRead(handle, intKeyId, sizeof(intKeyId)) != OK)
goto cleanup;
pkey = secKeyStoreGet(intKeyId);
if (!pkey)
goto cleanup;
if (EVP_PKEY_cmp(pkey, certPubKey) == 1)
{
if (keyId && *keyIdLen > 0)
{
/* coverity[check_after_deref] */
if ( keyIdLen && (size_t) *keyIdLen>strlen(intKeyId))
(void)strncpy_s(keyId, (size_t)(*keyIdLen), intKeyId, sizeof(intKeyId));
else
keyId[0] = 0;
}
if (keyIdLen)
*keyIdLen = (int)strlen(intKeyId);
break;
}
EVP_PKEY_free(pkey);
pkey = NULL;
}
if (!pkey)
errno = ENOENT;
cleanup:
EVP_PKEY_free(certPubKey);
if (handle)
(void)secKeyStoreClose(handle);
secSecretUnlock();
return pkey;
}
/*******************************************************************************
*
* secKeyStoreDel - Delete a key pair from the key store
*
* Delete a key pair from the key store
*
* RETURNS: OK if the key pair was successfully deleted, ERROR otherwise
*
* ERRNO:
* \is
* \i EINVAL
* Invalid arguments
* \i ENOENT
* No key pair found with this id
* \ie
*/
int secKeyStoreDel
(
const char * id
)
{
char filePath[SEC_SECRET_PATH_MAX];
int rc;
if (!id || strlen (id) > SEC_SECRET_KEY_ID_MAX)
{
errno = EINVAL;
return ERROR;
}
#if !defined (OPENSSL_NO_ENGINE) && defined (_WRS_CONFIG_TPM2_TSS)
if (secSecretGetFilePath (id, SEC_SECRET_TYPE_TPM2_KEY, filePath,
sizeof(filePath)) != OK)
#endif /* !OPENSSL_NO_ENGINE && _WRS_CONFIG_TPM2_TSS */
{
if (secSecretGetFilePath (id, SEC_SECRET_TYPE_PKEY, filePath,
sizeof(filePath)) != OK)
{
errno = ENOENT;
return ERROR;
}
}
secSecretLock ();
rc = unlink (filePath);
secSecretUnlock ();
return rc;
}
void* secKeyStoreOpen(void)
{
return secSecretOpenDir(SEC_SECRET_TYPE_PKEY);
}
STATUS secKeyStoreRead(void* handle,
char* keyId,
int len)
{
return secSecretRead(handle, keyId, len);
}
STATUS secKeyStoreClose(void* handle)
{
DIR* dir = handle;
return closedir(dir);
}
STATUS secKeyStoreReadyCheck()
{
char pFilePath[SEC_SECRET_PATH_MAX] = {0};
char *temp = NULL;
DEV_HDR * pDevHdr; /* device header */
if (secSecretGetDirPath (SEC_SECRET_TYPE_PKEY, pFilePath, sizeof(pFilePath)) != OK)
{
return ERROR;
}
temp = strstr(pFilePath, "/keys/");
if (temp == NULL)
{
return ERROR;
}
*temp = '\0';
temp = NULL;
pDevHdr = iosDevFindX (pFilePath, (const char **)&temp, FALSE);
if (pDevHdr == NULL)
{
return ERROR;
}
return OK;
}
@@ -0,0 +1,338 @@
/* secSecretCmd.c - Shell command to manage secrets in the vault */
/*
* Copyright (c) 2015-2017, 2019, 2021-2022 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
DESCRIPTION
This module implements the secret shell command
...
INCLUDE FILES: [N/A]
*/
/* includes */
#include <vxWorks.h>
#include <stdio.h>
#include <string.h>
#include <ioLib.h>
#include <shellInterpCmdLib.h>
#include <private/secSecretP.h>
/* defines */
/* typedefs */
/* globals */
/* locals */
/* forward declarations */
int secSecretCmd(int argc, char** argv);
LOCAL SHELL_CMD secSecretCmdData =
{
"secret",
secSecretCmd,
NULL,
"shell command to manage secrets in the vault",
"shell command to manage secrets in the vault",
"shell command to manage secrets in the vault"
};
/*******************************************************************************
*
* secSecretCmdUsage - secret shell command usage
*
* RETURNS: N/A
*
* ERRNO: N/A
*/
static void secSecretCmdUsage
(
void
)
{
printf("%s [options]:\n",secSecretCmdData.name);
printf("\tlist - list all secret's id\n");
printf("\timport <id> [secret] - import <secret> into vault and give it id <id>\n");
printf("\tdelete <id> - delete <id> from the vault\n");
printf("\tverify <id> [secret] - verify <id> with <secret>\n");
printf("\thelp|-h\n");
}
/*******************************************************************************
*
* secSecretCmdInit - Initialization routine of INCLUDE_SEC_SECRET_CMD
*
* RETURNS: N/A
*
* ERRNO: N/A
*/
void secSecretCmdInit
(
void
)
{
(void)shellCmdTopicAdd ("security",
"List of the shell commands related to security.");
(void)shellCmdAdd("security", &secSecretCmdData);
}
/*******************************************************************************
*
* secSecretCmdPromptSecret - Prompt for a secret
*
* Prompt of for a secret with echoing turned off
*
* RETURNS: OK if successful, ERROR otherwise
*
*/
static STATUS secSecretCmdPromptSecret
(
char* secret,
int len,
const char* label
)
{
int orgOpts;
int newOpts;
STATUS rc = ERROR;
printf("%s", label);
orgOpts = ioctl(STD_IN, FIOGETOPTIONS, 0);
if (orgOpts == ERROR)
return ERROR;
newOpts = orgOpts &= ~OPT_ECHO;
if (ioctl(STD_IN, FIOOPTIONS, newOpts) == ERROR)
return ERROR;
if (fgets(secret, len, stdin) == NULL)
goto exit;
while (strlen(secret) && (secret[strlen(secret)-1] == '\n' || secret[strlen(secret)-1] == '\r'))
secret[strlen(secret)-1] = 0;
rc = OK;
exit:
printf("\n");
(void)ioctl(STD_IN, FIOOPTIONS, orgOpts);
return rc;
}
/*******************************************************************************
*
* secSecretCmdImport - Import sub command of secret shell command
*
* RETURNS: OK if successful, ERROR otherwise
*/
int secSecretCmdImport
(
int argc,
char** argv
)
{
const char* id;
char* secret;
char buf[SEC_SECRET_MAX_SECRET];
char buf2[SEC_SECRET_MAX_SECRET];
id = argv[0];
if (argc == 1)
{
if (secSecretCmdPromptSecret(buf, SEC_SECRET_MAX_SECRET, "Enter secret: ") != OK)
return ERROR;
if (secSecretCmdPromptSecret(buf2, SEC_SECRET_MAX_SECRET, "Re-enter secret: ") != OK)
return ERROR;
if (strncmp(buf, buf2, SEC_SECRET_MAX_SECRET) != 0)
return ERROR;
secret = buf;
}
else if (argc == 2)
secret = argv[1];
else
{
secSecretCmdUsage();
return ERROR;
}
if (secSecretImport(id, secret, (int)strlen(secret)+1) != OK)
{
printf("Failed to import secret into vault!\n");
return ERROR;
}
return OK;
}
/*******************************************************************************
*
* secKeyStoreCmdVerify - Verify sub command of keyStore shell command
*
* RETURNS: OK if successful, ERROR otherwise
*
*/
int secSecretCmdVerify
(
int argc,
char** argv
)
{
const char* id;
char* secret;
char buf[SEC_SECRET_MAX_SECRET];
char ref[SEC_SECRET_MAX_SECRET];
int refLen = sizeof(ref);
id = argv[0];
if (argc == 1)
{
if (secSecretCmdPromptSecret(buf, SEC_SECRET_MAX_SECRET, "Enter secret: ") != OK)
return ERROR;
secret = buf;
}
else if (argc == 2)
secret = argv[1];
else
{
secSecretCmdUsage();
return ERROR;
}
if (secSecretGet(id, ref, &refLen) != OK)
{
printf("No %s id in vault!\n", id);
return ERROR;
}
if ((size_t)refLen != strlen(secret)+1 || ref[refLen-1] != 0 || strcmp(ref, secret) !=0)
{
printf("Incorrect value!\n");
return ERROR;
}
printf("Correct value!\n");
return OK;
}
/*******************************************************************************
*
* secKeyStoreDelete - Delete sub command of keyStore shell command
*
* RETURNS: OK if successful, ERROR otherwise
*
*/
int secSecretCmdDelete
(
int argc,
char** argv
)
{
const char* id;
if (argc != 1)
{
secSecretCmdUsage();
return ERROR;
}
id = argv[0];
return secSecretDel(id);
}
/*******************************************************************************
*
* secKeyStoreList - List sub command of keyStore shell command
*
* RETURNS: OK if successful, ERROR otherwise
*
*/
int secSecretCmdList
(
int argc,
char** argv
)
{
char name[SEC_SECRET_KEY_ID_MAX+1];
void* handle;
(void)argc;
(void)argv;
handle = secSecretOpen();
if (!handle)
return ERROR;
while (1)
{
if (secSecretRead(handle, name, sizeof(name)) != OK)
{
(void)secSecretClose(handle);
return OK;
}
printf("%s\n", name);
}
return OK;
}
/*******************************************************************************
*
* secSecretCmd - secret shell command
*
* See secSecretCmdUsage for a usage description of the command
*
* RETURNS: OK if successful, ERROR otherwise
*/
int secSecretCmd
(
int argc,
char** argv
)
{
const char* cmd;
if (argc < 2)
{
secSecretCmdUsage();
return ERROR;
}
cmd = argv[1];
argc -= 2;
argv += 2;
if (strcmp(cmd, "import") == 0)
{
return secSecretCmdImport(argc, argv);
}
if (strcmp(cmd, "delete") == 0)
{
return secSecretCmdDelete(argc, argv);
}
if (strcmp(cmd, "verify") == 0)
{
return secSecretCmdVerify(argc, argv);
}
if (strcmp(cmd, "list") == 0)
return secSecretCmdList(argc, argv);
if ((strcmp(cmd, "help") == 0)||(strcmp(cmd, "-h") == 0))
{
secSecretCmdUsage();
return ERROR;
}
printf("vault: unknown sub-command: %s.\n", cmd);
secSecretCmdUsage();
return ERROR;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,589 @@
/* secTrustStoreImxProvider.c - NXP i.MX6 trust store provider */
/*
* Copyright (c) 2017-2019, 2021 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
DESCRIPTION
This file implements a trust public key store provider on an NXP i.MX6
series SoC. It verifies the RSA public key by using a Super Root Key
(SRK) table stored in ROMFS and an SRK hash stored in the on-chip eFUSE OTP.
The SRK table and SRK hash generated by the srktool of the CST can
contain up to four separate public keys. Only one SRK can be selected
at boot time through an Install SRK CSF command. The i.MX 6 Series
supports revocation of SRKs. You can revoke an SRK on i.MX 6 Series devices.
There are three SRK Revoke fuse bits that map to the first three SRK table
indexes. To revoke an SRK, burn the corresponding bit in the SRK_REVOKE eFuse
field.
Trust key store provider has three steps to verify an RSA public key.
1. Match the RSA public key in the SRK table and get the key index.
2. Check for revocation of SRKs.
3. Use the SRK hash to verify the SRK table.
INCLUDE FILES: vxWorks.h secHash.h
*/
/* includes */
#include <vxWorks.h>
#include <ioLib.h>
#include <string.h>
#include <secHash.h>
#include <secTrustStore.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/x509v3.h>
/* defines */
#define SRK_TAG (0xE1)
#define SRK_ALGORITHM (0x21)
#define SRK_CA_EN (0x80)
#define SRK_CA_DIS (0x00)
#define SRK_TABLE_OFFSET (0x04)
#define SRK_HEADER_LEN (12)
#define SRK_MAX_CNT (4)
#define IMX_OCOTP_SRK_HASH_LEN (32)
#define IMX_OCOTP_SRK_REVOKE_LEN (4)
#define IMX_OCOTP_SRK_HASH_OFFSET (0x60)
#define IMX_OCOTP_SRK_REVOKE_OFFSET (0xbc)
#ifndef ARMBE8
#define SRK_SWAP16(val) ((UINT16)((val >> 8) | (val << 8)));
#else
#define SRK_SWAP16(val)
#endif /* ARMBE8 */
/* typedefs */
typedef struct srkHeader
{
UINT8 tag;
UINT16 length;
UINT8 algorithm;
UINT8 reserved0;
UINT8 reserved1;
UINT8 reserved2;
UINT8 flags;
UINT16 modulusLen;
UINT16 exponentLen;
}__attribute__((packed)) SRK_HEADER;
/* externs */
IMPORT const char srkArrayStart[];
IMPORT const char srkArrayEnd[];
/* locals */
LOCAL char * ocotpDevName = NULL;
/* forward declarations */
LOCAL STATUS imxOcotpReadSrk (UINT8 * pSrkHash, UINT32 * pRevokeMask);
LOCAL STATUS imxReadKeyTable (int index, UINT8 * pKeyTable, UINT32 len);
LOCAL STATUS imxVerifyPubKey (UINT8 * pKeyTable, UINT32 keyTableLen);
LOCAL STATUS imxCreateKeyTable (X509 * pX509, UINT8 ** ppKeyTable, UINT32 *
pKeyTableLen);
LOCAL STATUS imxPubKeyValidateProvider (const char * trustStoreId, const X509 *
pX509, const unsigned int keyUsage);
/*******************************************************************************
*
* imxOcotpReadSrk - read the SRK hash value and revoke the mask from the OCOTP
*
* This function reads the SRK hash value and revokes the mask from the
* on-chip OTP controller.
*
* RETURNS: OK if the operation is successful. Otherwise, ERROR
*
* ERRNO: N/A
*/
LOCAL STATUS imxOcotpReadSrk
(
UINT8 * pSrkHash,
UINT32 * pRevokeMask
)
{
int fd;
ssize_t readSize;
if ((pSrkHash == NULL) || (pRevokeMask == NULL))
return ERROR;
fd = open (ocotpDevName, O_RDONLY, 0666);
if (fd < 0)
return ERROR;
if (lseek (fd, IMX_OCOTP_SRK_HASH_OFFSET, SEEK_SET) == ERROR)
{
(void)close (fd);
return ERROR;
}
readSize = IMX_OCOTP_SRK_HASH_LEN;
if (read (fd, (char *)pSrkHash, (size_t) readSize) != readSize)
{
(void)close (fd);
return ERROR;
}
if (lseek (fd, IMX_OCOTP_SRK_REVOKE_OFFSET, SEEK_SET) == ERROR)
{
(void)close (fd);
return ERROR;
}
readSize = IMX_OCOTP_SRK_REVOKE_LEN;
if (read (fd, (char *)pRevokeMask, (size_t) readSize) != readSize)
{
(void)close (fd);
return ERROR;
}
(void)close (fd);
return OK;
}
/*******************************************************************************
*
* imxReadKeyTable - read the SRK table from the file
*
* This function reads an SRK table from a file.
*
* RETURNS: OK if the operation is successful. Otherwise, ERROR
*
* ERRNO: N/A
*/
LOCAL STATUS imxReadKeyTable
(
int index,
UINT8 * pKeyTable,
UINT32 len
)
{
if (pKeyTable == NULL)
return ERROR;
if (SRK_TABLE_OFFSET + len * (unsigned int)index > (unsigned int)(srkArrayEnd - srkArrayStart))
return ERROR;
(void)memcpy (pKeyTable,
&srkArrayStart[SRK_TABLE_OFFSET + len * (unsigned int) index], len);
return OK;
}
/*******************************************************************************
*
* imxCreateKeyTable - create the SRK table for the public key
*
* This function creates the SRK table for the public key.
*
* RETURNS: OK if the operation successfully, ERROR otherwise
*
* ERRNO: N/A
*/
LOCAL STATUS imxCreateKeyTable
(
X509 * pX509,
UINT8 ** ppKeyTable,
UINT32 * pKeyTableLen
)
{
EVP_PKEY * pPubKey = NULL;
RSA * pRsa = NULL;
UINT8 * pKeyTable = NULL;
BASIC_CONSTRAINTS * pBs = NULL;;
STATUS ret = ERROR;
UINT32 keyLen;
SRK_HEADER srkHeader;
if ((pX509 == NULL) || (ppKeyTable == NULL) || (pKeyTableLen == NULL))
return ret;
pPubKey = X509_get_pubkey (pX509);
if (pPubKey == NULL)
return ret;
pRsa = EVP_PKEY_get1_RSA (pPubKey);
if ((pRsa == NULL) || (RSA_get0_n(pRsa) == NULL) || (RSA_get0_e(pRsa) == NULL))
goto cleanup;
keyLen = sizeof (SRK_HEADER) + (UINT32) BN_num_bytes (RSA_get0_n(pRsa)) +
(UINT32) BN_num_bytes (RSA_get0_e(pRsa));
pKeyTable = calloc (1, keyLen);
if (pKeyTable == NULL)
goto cleanup;
memset (&srkHeader, 0x0, sizeof (SRK_HEADER));
srkHeader.tag = SRK_TAG;
srkHeader.length = SRK_SWAP16 (keyLen);
srkHeader.algorithm = SRK_ALGORITHM;
srkHeader.modulusLen = SRK_SWAP16 (BN_num_bytes (RSA_get0_n(pRsa)));
srkHeader.exponentLen = SRK_SWAP16 (BN_num_bytes (RSA_get0_e(pRsa)));
pBs = X509_get_ext_d2i (pX509, NID_basic_constraints, NULL, NULL);
if (pBs == NULL)
{
free (pKeyTable);
pKeyTable = NULL;
goto cleanup;
}
if (pBs->ca == 0)
srkHeader.flags = SRK_CA_DIS;
else
srkHeader.flags = SRK_CA_EN;
memcpy ((void *)pKeyTable, (void *)&srkHeader, sizeof (SRK_HEADER));
(void)BN_bn2bin (RSA_get0_n(pRsa), (pKeyTable + sizeof (SRK_HEADER)));
(void)BN_bn2bin (RSA_get0_e(pRsa),
(pKeyTable + sizeof (SRK_HEADER) + BN_num_bytes (RSA_get0_n(pRsa))));
*ppKeyTable = pKeyTable;
*pKeyTableLen = keyLen;
ret = OK;
cleanup:
if (pRsa != NULL)
RSA_free(pRsa);
if (pPubKey != NULL)
EVP_PKEY_free (pPubKey);
if (pBs != NULL)
BASIC_CONSTRAINTS_free(pBs);
return ret;
}
/*******************************************************************************
*
* imxVerifyPubKey - check if a public key is trusted
*
* This function checks if the public key provided in the publicKey argument
* is trusted.
*
* RETURNS: OK if the public key is trusted. Otherwise, ERROR
*
* ERRNO: N/A
*/
LOCAL STATUS imxVerifyPubKey
(
UINT8 * pKeyTable,
UINT32 keyTableLen
)
{
UINT8 * pTableItem = NULL;
UINT32 revokeMask = 0;
UINT8 keyCnt = 0;
STATUS ret = ERROR;
UINT32 hashLen = SEC_HASH_DIGEST_LEN_SHA256;
UINT8 * pKey;
SEC_HASH_CTX ctx;
int index;
UINT8 srkHash[SEC_HASH_DIGEST_LEN_SHA256];
UINT8 allKeysHash[SEC_HASH_DIGEST_LEN_SHA256 * SRK_MAX_CNT];
UINT8 finalHash[SEC_HASH_DIGEST_LEN_SHA256];
int i;
pTableItem = calloc (1, keyTableLen);
if (pTableItem == NULL)
return ret;
for (keyCnt = 0; keyCnt < SRK_MAX_CNT; keyCnt++)
{
if (imxReadKeyTable (keyCnt, pTableItem, keyTableLen) == OK)
{
if (memcmp ((void *)pKeyTable, (void *)pTableItem, keyTableLen) ==
0)
{
index = keyCnt;
ret = OK;
}
}
else
break;
}
if (ret != OK)
goto cleanup;
memset ((void *)srkHash, 0x0, SEC_HASH_DIGEST_LEN_SHA256);
ret = imxOcotpReadSrk (srkHash, &revokeMask);
if (ret != OK)
goto cleanup;
/*
* Only the first three SRKs in a table can be revoked.
*/
if (((0x1 << index) & (revokeMask & 0x7)) != 0)
{
ret = ERROR;
goto cleanup;
}
memset ((void *)allKeysHash, 0x0,
(SEC_HASH_DIGEST_LEN_SHA256 * SRK_MAX_CNT));
for (i = 0; i < keyCnt; i++)
{
ret = secHashInit (&ctx, secHashSha256TemplateGet());
if (ret != OK)
goto cleanup;
if (index == i)
pKey = pKeyTable;
else
{
if (imxReadKeyTable (i, pTableItem, keyTableLen) == OK)
pKey = pTableItem;
else
{
secHashCleanup (&ctx);
ret = ERROR;
goto cleanup;
}
}
ret = secHashUpdate (&ctx, (void *)pKey, (size_t)keyTableLen);
if (ret != OK)
{
secHashCleanup (&ctx);
goto cleanup;
}
ret = secHashFinal (&ctx, &allKeysHash[SEC_HASH_DIGEST_LEN_SHA256 * i],
&hashLen);
if (ret != OK)
{
secHashCleanup (&ctx);
goto cleanup;
}
secHashCleanup (&ctx);
}
ret = secHashInit (&ctx, secHashSha256TemplateGet());
if (ret != OK)
goto cleanup;
ret = secHashUpdate (&ctx, (void *)allKeysHash,
(size_t)(SEC_HASH_DIGEST_LEN_SHA256 * keyCnt));
if (ret != OK)
{
secHashCleanup (&ctx);
goto cleanup;
}
ret = secHashFinal (&ctx, finalHash, &hashLen);
if (ret != OK)
{
secHashCleanup (&ctx);
goto cleanup;
}
secHashCleanup (&ctx);
if (memcmp (finalHash, srkHash, SEC_HASH_DIGEST_LEN_SHA256) == 0)
ret = OK;
else
ret = ERROR;
cleanup:
if (pTableItem != NULL)
{
memset ((void *)pTableItem, 0x0, keyTableLen);
free (pTableItem);
}
memset ((void *)srkHash, 0x0, (SEC_HASH_DIGEST_LEN_SHA256));
memset ((void *)allKeysHash, 0x0,
(SEC_HASH_DIGEST_LEN_SHA256 * SRK_MAX_CNT));
memset ((void *)finalHash, 0x0, (SEC_HASH_DIGEST_LEN_SHA256));
return ret;
}
/*******************************************************************************
*
* imxPubKeyValidateProvider - check if a public key is trusted
*
* This function checks if the public key provided in the publicKey argument
* is trusted.
*
* RETURNS: OK if the public key is trusted. Otherwise, ERROR
*
* ERRNO: N/A
*/
LOCAL STATUS imxPubKeyValidateProvider
(
const char * trustStoreId, /* Currently not used */
const X509 * pX509,
const unsigned int keyUsage /* Currently not used */
)
{
STATUS ret = ERROR;
UINT8 * pKeyTable;
UINT32 keyTableLen;
if (pX509 == NULL)
return ret;
ret = imxCreateKeyTable ((X509 *)pX509, &pKeyTable, &keyTableLen);
if (ret != OK)
return ret;
ret = imxVerifyPubKey (pKeyTable, keyTableLen);
free (pKeyTable);
return ret;
}
/*******************************************************************************
*
* secTrustStoreImxPubKeyValidateInit - initiate the i.MX6 trust store
*
* This function is the initialization routine of the INCLUDE_IMX_TRUST_STORE
* component.
*
* RETURNS: N/A
*
* ERRNO: N/A
*
* \NOMANUAL
*/
void secTrustStoreImxPubKeyValidateInit
(
const char * devName
)
{
if (devName == NULL)
{
return;
}
if ((ocotpDevName = (char *)realloc (ocotpDevName,
strlen(devName) + 1)) != NULL)
{
(void)strncpy (ocotpDevName, devName, strlen(devName) + 1);
}
else
{
return;
}
secTrustStorePubKeyValidateProviderSet (imxPubKeyValidateProvider);
}
#undef IMX_PUB_KEY_STORE_DEBUG
#ifdef IMX_PUB_KEY_STORE_DEBUG
/*******************************************************************************
*
* readPemFile - get certification from PEM file
*
* This function gets X509 certification from the PEM file in ROMFS.
*
* RETURNS: X509 certification
*
* ERRNO: N/A
*
* \NOMANUAL
*/
LOCAL X509 * readPemFile
(
BOOL isTrustedKey
)
{
char * file;
X509 * pX509 = NULL;
FILE * fd;
if (isTrustedKey)
file = "/romfs/SRK1_sha256_2048_65537_v3_ca_crt.pem";
else
file = "/romfs/SRK1_sha256_2048_65537_v3_usr_crt.pem";
fd = fopen (file, "r");
if (fd == NULL)
{
printf ("Failed to open certificate file: %s\n", file);
return pX509;
}
pX509 = PEM_read_X509 (fd, NULL, NULL, NULL);
if (pX509 == NULL)
(void)printf ("Failed to read certificate file: %s\n", file);
(void)fclose (fd);
return pX509;
}
/*******************************************************************************
*
* imx6PubKeyValidateTest - test the i.MX6 public key validation function
*
* This function gets the public key from the PEM file and validates the key with
* imxVerifyPubKey. It is used to test the i.MX6 trust store.
*
* RETURNS: OK if the key verification passes. Otherwise, ERROR
*
* ERRNO: N/A
*
* \NOMANUAL
*/
STATUS imx6PubKeyValidateTest
(
BOOL isTrustedKey
)
{
X509 * pX509 = NULL;
STATUS ret = ERROR;
UINT8 * pKeyTable;
UINT32 keyTableLen;
pX509 = readPemFile (isTrustedKey);
if (pX509 == NULL)
return ret;
ret = imxCreateKeyTable (pX509, &pKeyTable, &keyTableLen);
if (ret != OK)
return ret;
ret = imxVerifyPubKey (pKeyTable, keyTableLen);
free (pKeyTable);
if (ret == OK)
printf ("Verification PASS!\n");
else
printf ("Verification FAIL!\n");
return ret;
}
#endif /* IMX_PUB_KEY_STORE_DEBUG */
@@ -0,0 +1,100 @@
/* secTrustStoreLib.c - Trust Store Lib */
/*
* Copyright (c) 2017, 2020-2021 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
DESCRIPTION
The trust store provides an API that enables you to check on whether
a public key is trusted or not.
This can be used by, for example, the secure ELF loader in order to determine
if a public key used to verify a signature on ELF files is trusted.
The library also provides the ability to install different providers for
the trust check.
CONFIGURATION
The SECURITY_MISC_SEC_CRYPTO layer is included by default in the Source Build
Configuration.
The Kernel Configuration components will depend on the type of trusted key store. See
the VxWorks Security Programmer's Guide for more information.
INCLUDE FILES: secTrustStore.h
SEE ALSO
\tb [VxWorks Security Programmer's Guide](https://docs.windriver.com/bundle/vxworks_security_programmers_guide_@vx_release/page/pcp1496697106766.html)
*/
/* includes */
#include <vxWorks.h>
#include <errno.h>
#include <secTrustStore.h>
/* defines */
/* typedefs */
/* globals */
/* locals */
SEC_TRUST_STORE_PUBKEY_VALIDATE_CB secTrustStorePubKeyValidateProvider;
/* forward declarations */
/*******************************************************************************
*
* secTrustStorePubKeyValidate - check if a public key is trusted
*
* This function calls the installed provider in order to check if the public key
* provided in the publicKey argument is trusted or not.
*
* RETURNS: OK, if the public key is trusted, otherwise ERROR
*
* ERRNO:
* \is
* \i ENOTSUP
* No provider installed
* \ie
* \NOMANUAL
*/
STATUS secTrustStorePubKeyValidate
(
const char* trustStoreId,
const X509* cert,
const unsigned int keyUsage)
{
if (secTrustStorePubKeyValidateProvider != NULL)
{
return secTrustStorePubKeyValidateProvider(trustStoreId, cert, keyUsage);
}
errno = ENOTSUP;
return ERROR;
}
/*******************************************************************************
*
* secTrustStorePubKeyValidateProviderSet - install a trust store provider
*
* This function install a trust store provider.
*
* RETURNS: N/A
*
* ERRNO: N/A
*/
void secTrustStorePubKeyValidateProviderSet
(
SEC_TRUST_STORE_PUBKEY_VALIDATE_CB provider
)
{
secTrustStorePubKeyValidateProvider = provider;
}
@@ -0,0 +1,147 @@
/* secTrustStoreStaticProvider.c - static trust store provider */
/*
* Copyright (c) 2017, 2021 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
DESCRIPTION
This file implements a trust store provider. The trusted key is configured as a static CDF parameter,
hence the name static trust store provider.
...
INCLUDE FILES: [N/A]
*/
/* includes */
#include <vxWorks.h>
#include <secTrustStore.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
/* defines */
/* typedefs */
/* globals */
extern const char* pemEncodedTrustedCert; /* from the configlette */
/* locals */
/* forward declarations */
/*******************************************************************************
*
* secTrustStoreStaticX509Validate - check if a public key is trusted
*
* This function checks if the public key provided in the publicKey argument
* is trusted.
*
* RETURNS: OK, if the public key is trusted, otherwise ERROR.
*
* ERRNO: N/A
*/
LOCAL STATUS secTrustStoreStaticX509Validate
(
const char* trustStoreId,
const X509* cert,
const unsigned int keyUsage
)
{
EVP_PKEY* trustedPublicKey = NULL;
EVP_PKEY* publicKey = NULL;
X509* trustedCert = NULL;
BIO* bio;
STATUS ret = ERROR;
(void)trustStoreId; /* Currently not used */
(void)keyUsage; /* Currently not used */
if (pemEncodedTrustedCert == NULL)
{
return ERROR;
}
bio = BIO_new_mem_buf ((void*)pemEncodedTrustedCert, -1);
if (bio == NULL)
{
return ERROR;
}
publicKey = X509_get_pubkey ((X509*)cert);
if (publicKey == NULL)
{
goto cleanup;
}
while ((trustedCert = PEM_read_bio_X509 (bio, NULL, NULL, NULL)) != NULL)
{
trustedPublicKey = X509_get_pubkey (trustedCert);
if (trustedPublicKey == NULL)
{
/* Bad certificate, skip it */
X509_free(trustedCert);
continue;
}
if (EVP_PKEY_cmp (trustedPublicKey, publicKey) == 1)
{
ret = OK;
break;
}
X509_free(trustedCert);
EVP_PKEY_free(trustedPublicKey);
trustedPublicKey = NULL;
}
cleanup:
BIO_free_all(bio);
if (trustedCert)
{
X509_free (trustedCert);
}
if (trustedPublicKey)
{
EVP_PKEY_free (trustedPublicKey);
}
if (publicKey)
{
EVP_PKEY_free (publicKey);
}
return ret;
}
/*******************************************************************************
*
* secTrustStoreStaticX509ValidateInit - initiate the static trust store
*
* This function is the initialization routine of the INCLUDE_STATIC_TRUST_STORE
* component.
*
* RETURNS: N/A
*
* ERRNO: N/A
*/
void secTrustStoreStaticX509ValidateInit
(
void
)
{
secTrustStorePubKeyValidateProviderSet (secTrustStoreStaticX509Validate);
}
@@ -0,0 +1,185 @@
/*
* Copyright (c) 2017, 2019, 2021 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
#include <vxWorks.h>
#include <ioLib.h>
#include <string.h>
#include <secHash.h>
#include <secTrustStore.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/x509v3.h>
#include <ctype.h>
#include <private/secUefiDbP.h>
#include <private/ImageAuthentication.h>
#include <private/uefiTrustStoreP.h>
/* defines */
/* typedefs */
/* locals */
/*******************************************************************************
*
* secTrustStoreUefiX509Validate - validate a public key
*
* This function validates a public key provided in the publicKey argument.
*
* RETURNS: OK, if the public key is trusted, otherwise ERROR.
*
* ERRNO: N/A
*/
LOCAL STATUS secTrustStoreUefiX509Validate
(
const char* trustStoreId,
const X509 * x509Cert,
const unsigned int keyUsage
)
{
UEFI_DB_INFO * pUefiWhtDbInfo = NULL; /* white list info */
EFI_GUID efiCertX509GUID = EFI_CERT_X509_GUID;
EFI_SIGNATURE_LIST * pWhtSig = NULL;
EFI_SIGNATURE_LIST * pWhtSigEnd = NULL;
EFI_SIGNATURE_DATA * pData = NULL;
EVP_PKEY* trustedPublicKey = NULL;
EVP_PKEY* publicKey = NULL;
X509 * trustCert = NULL;
const unsigned char * buf = NULL;
size_t certlen;
uint64_t sz = 0;
uint32_t version = 0;
STATUS ret = ERROR;
(void)trustStoreId; /* Currently not used */
(void)keyUsage; /* Currently not used */
/* Set the first EFI signature list. */
pUefiWhtDbInfo = (UEFI_DB_INFO *)uefiDatabase;
version = pUefiWhtDbInfo->version;
sz = pUefiWhtDbInfo->white_db_size;
if (version != UEFI_DATABASE_VERSION)
{
goto Errout;
}
pWhtSig = (EFI_SIGNATURE_LIST *)(&pUefiWhtDbInfo->efiSignatureList[0]);
pWhtSigEnd = (EFI_SIGNATURE_LIST *)((UINT8 *)pWhtSig + sz -
(sizeof (EFI_SIGNATURE_LIST) + sizeof (EFI_SIGNATURE_DATA)));
/* extract public key from certificate */
publicKey = X509_get_pubkey ((X509*)x509Cert);
if (publicKey == NULL)
{
goto Errout;
}
while (pWhtSig < pWhtSigEnd)
{
/*
* Check for the existence of the X509 certificate from the data
* in the whitelist DB.
*/
if (memcmp (&(pWhtSig->SignatureType), &efiCertX509GUID,
sizeof (EFI_GUID)) != 0)
{
break;
}
/* Locate the X509 certificate from the data in the whitelist DB. */
pData = (EFI_SIGNATURE_DATA *)((UINT8 *)pWhtSig +
sizeof (EFI_SIGNATURE_LIST));
certlen = (size_t)(pWhtSig->SignatureSize) - sizeof (pData->SignatureOwner);
/* read certificate out of data */
buf = (const unsigned char *)((UINT8 *)pWhtSig +
sizeof (EFI_SIGNATURE_LIST) +
sizeof (EFI_GUID));
trustCert = d2i_X509(NULL, &buf, (long) certlen);
if (trustCert == NULL)
{
break;
}
/* extract public key from trusted certificate */
trustedPublicKey = X509_get_pubkey (trustCert);
if (trustedPublicKey == NULL)
{
break;
}
if (EVP_PKEY_cmp (trustedPublicKey, publicKey) == 1)
{
ret = OK;
break;
}
/* Increment to the next EFI signature list. */
X509_free (trustCert);
EVP_PKEY_free (trustedPublicKey);
trustCert = NULL;
trustedPublicKey = NULL;
pWhtSig = (EFI_SIGNATURE_LIST *)((UINT8 *)pWhtSig +
sizeof (EFI_SIGNATURE_LIST) + pWhtSig->SignatureSize);
}
Errout:
if (trustCert != NULL)
{
X509_free (trustCert);
}
if (trustedPublicKey != NULL)
{
EVP_PKEY_free (trustedPublicKey);
}
if (publicKey != NULL)
{
EVP_PKEY_free (publicKey);
}
return ret;
}
/*******************************************************************************
*
* secTrustStoreUefiX509ValidateInit - initialize the UEFI database trust store
*
* This function is the initialization routine of the INCLUDE_UEFI_DB_TRUST_STORE
* component.
*
* RETURNS: N/A
*
* ERRNO: N/A
*/
void secTrustStoreUefiX509ValidateInit
(
void
)
{
secTrustStorePubKeyValidateProviderSet (secTrustStoreUefiX509Validate);
}
@@ -0,0 +1,58 @@
/* secVaultCmd.c - Wrapper to secret shell command */
/*
* Copyright (c) 2014-2017, 2021 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
DESCRIPTION
This module implements the 'vault' shell command. A shell command wrapper for the 'secret'
shell command.
...
INCLUDE FILES: [N/A]
*/
/* includes */
#include <vxWorks.h>
#include <stdio.h>
#include <string.h>
#include <ioLib.h>
#include <shellInterpCmdLib.h>
/* defines */
/* typedefs */
/* globals */
/* locals */
/* forward declarations */
int secSecretCmd(int argc, char** argv);
int secVaultCmd(int argc, char** argv);
LOCAL SHELL_CMD secVaultCmdData =
{
"vault",
secVaultCmd,
NULL,
"shell command to manage secrets in the vault",
"shell command to manage secrets in the vault",
"shell command to manage secrets in the vault"
};
void secVaultCmdInit(void)
{
(void)shellCmdTopicAdd ("security",
"List of the shell commands related to security.");
(void)shellCmdAdd("security", &secVaultCmdData);
}
int secVaultCmd(int argc, char** argv)
{
printf("The vault shell command has been deprecated. Please use the secret shell command instead\n");
return secSecretCmd(argc, argv);
}
@@ -0,0 +1,43 @@
/* secVaultKepObfuscator.c - Key-encryption-password obfuscator */
/*
* Copyright (c) 2015, 2017, 2021 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
DESCRIPTION
This module is an example of the Wind River Systems C coding conventions.
...
INCLUDE FILES: [N/A]
*/
/* includes */
/* defines */
/* typedefs */
/* globals */
/* locals */
/* forward declarations */
#include <vxWorks.h>
#include <secSecret.h>
#include <string.h>
int secVaultKepObfuscator(char* buf, int* len);
void secVaultKepObfuscatorInit (void)
{
SEC_VAULT_KEP_BACKEND kepBackend = {0};
kepBackend.kepGet = secVaultKepObfuscator;
(void)secVaultKepBackendSet (&kepBackend);
}
@@ -0,0 +1,28 @@
# Makefile - SECURITY_MISC SEC_HASH layer Makefile
#
# Copyright (c) 2019, 2021 Wind River Systems, Inc.
#
# The right to copy, distribute, modify or otherwise make use
# of this software may be licensed only pursuant to the terms
# of an applicable Wind River license agreement.
#
# Customers wishing an alternate hash code implementation can set the WR_HASH_DISABLE=y
# in a common.vxconfig file in their new layer, this allows the SEC_HASH code to be built
# which provides a VxWorks API for hash algorithms, hmac and pbkdf2. Different implementations
# of the hash algorithms can be plugged in without affecting the user of the APIs.
# Note that no implementation of hash algorithms are included in the SEC_HASH code.
# The WR provided implementations are based on openssl and are placed in the HASH layer.
# A user of the SEC_HASH hash API must therefore either include the HASH layer or
# provide its own set of hash algorithm implementations.
# Provides VxWorks Hash, HMAC, and PBKDF2 APIs
KERNEL_PUBLIC_H_DIRS += h
BUILD_DIRS += src
POST_NOBUILD_CDFDIRS += cdf
POST_NOBUILD_CFGDIRS += cfg
CC_WARNINGS_BUILD_DIRS = CC_WARNINGS_HIGH_SYS
CC_WARNINGS_BUILD_USER_DIRS = CC_WARNINGS_HIGH_SYS
include $(WIND_KRNL_MK)/rules.layers.mk
@@ -0,0 +1,30 @@
# Makefile - makefile for sec_hash
#
# Copyright (c) 2015, 2021 Wind River Systems, Inc.
#
# The right to copy, distribute, modify or otherwise make use
# of this software may be licensed only pursuant to the terms
# of an applicable Wind River license agreement.
#
# DESCRIPTION
# Makefile for sec_hash
#
LIB_BASE_NAME = SEC_HASH
include $(WIND_KRNL_MK)/defs.library.mk
OBJS = secHash.o
OBJS += secHmac.o
OBJS += secHashMd5.o
OBJS += secPbkdf2.o
OBJS += secHashSha1.o
OBJS += secHashSha256.o
OBJS += secHashSha384.o
OBJS += secHashSha512.o
OBJS += secHashRmd.o
OBJS += secHashWhirlpool.o
DOC_FILES = secHash.c secHmac.c secPbkdf2.c
include $(WIND_KRNL_MK)/rules.library.mk
@@ -0,0 +1,298 @@
/* secHash.c - VxWorks hash library */
/*
* Copyright (c) 2015, 2017, 2019, 2021 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
DESCRIPTION
This file implements the VxWorks hash API. The API separates the application
using a hash algorithm from the provider. The application specifies what hash
algorithm to use by means of a template. The template is used to initialize a
cipher context. The API is designed in such a way that once the hash context is
initialized, the application does not need keep track of the hash algorithm used.
That is all encapsulated by the API.
A typical usage of the hash API is shown below. It shows how to hash three buffers
using SHA256.
\cs
SEC_HASH_CTX ctx;
unsigned char[32] digest;
unsigned int dgst_len = sizeof(digest);
secHashInit(&ctx, secHashSha256TemplateGet());
secHashUpdate(&ctx, data1, len1);
secHashUpdate(&ctx, data2, len2);
secHashUpdate(&ctx, data3, len3);
secHashFinal(&ctx, digest, &dgst_len);
secHashCleanup(&ctx);
\ce
TEMPLATE FUNCTIONS
The following template functions exist:
\cs
const SEC_HASH_TEMPLATE* secHashMd5TemplateGet(void);
const SEC_HASH_TEMPLATE* secHashRmdTemplateGet(void);
const SEC_HASH_TEMPLATE* secHashSha1TemplateGet(void);
const SEC_HASH_TEMPLATE* secHashSha256TemplateGet(void);
const SEC_HASH_TEMPLATE* secHashSha384TemplateGet(void);
const SEC_HASH_TEMPLATE* secHashSha512TemplateGet(void);
\ce
A proprietary implementation of a hash algorithms can be installed by calling
set template function for that particular algorithm. The following set template
functions exist:
\cs
void secHashMd5TemplateSet(const SEC_HASH_TEMPLATE* ctx);
void secHashRmdTemplateSet(const SEC_HASH_TEMPLATE* ctx);
void secHashSha1TemplateSet(const SEC_HASH_TEMPLATE* ctx);
void secHashSha256TemplateSet(const SEC_HASH_TEMPLATE* ctx);
void secHashSha384TemplateSet(const SEC_HASH_TEMPLATE* ctx);
void secHashSha512TemplateSet(const SEC_HASH_TEMPLATE* ctx);
\ce
The SECURITY_MISC_SEC_HASH layer is included by default in the Source Build
Configuration.
Depending on which algorithm is used, add the INCLUDE_SEC_HASH_* component to the
Kernel Configuration.
INCLUDE FILES: secHash.h
SEE ALSO
\tb [VxWorks Cryptography Libraries Programmer's Guide](https://docs.windriver.com/bundle/vxworks_cryptography_libraries_programmers_guide_@vx_release/page/sgr1441901569970.html)
*/
/* includes */
#include <secHash.h>
#include <string.h>
#if !defined(_WRS_CONFIG_OPENSSL) && !defined(_WRS_CONFIG_MBEDTLS_HASH)
#error "Please choose at least one hash algorithm provider , OpenSSL or Mbed TLS "
#endif
/*******************************************************************************
*
* secHash - Calculate a hash digest
*
* This function can only be used if the data to hash is in one continuous buffer.
* secHashInit, secHashUpdate, secHashFinal and secHashCleanup must be used if
* the data to hash is stored in two or more buffers.
*
* ARGUMENTS
* \is
* \i data
* pointer to the data that the will be included in the hash calculation
* \i len
* number of bytes to include in the hash calculation
* \i digest
* pointer to the buffer where the digest (or hash) data will be written
* \i digestLen
* length of the digest buffer
* \i hash_template
* controls the hash algorithm to use, e.g. use the return value of secHashSha1TemplateGet().
* \ie
*
* RETURNS: OK if the hash was successfully calculated, ERROR otherwise.
*
* ERRNO: N/A
*/
STATUS secHash
(
const void* data,
size_t len,
unsigned char* digest,
unsigned int *digestLen,
const SEC_HASH_TEMPLATE* hash_template
)
{
SEC_HASH_CTX ctx;
STATUS rc;
rc = secHashInit(&ctx, hash_template);
if (rc != OK)
return rc;
rc = secHashUpdate(&ctx, data, len);
if (rc != OK)
{
secHashCleanup(&ctx);
return rc;
}
rc = secHashFinal(&ctx, digest, digestLen);
secHashCleanup(&ctx);
return rc;
}
/*******************************************************************************
*
* secHashInit - Initialize a hash context
*
* This function initializes a hash context. The hash algorithm to use is specified
* by the hash_template argument. For instance, in order to use SHA1, the return value of
* secHashSha1TemplateGet() should be used as template. Not that every successful
* call to secHashInit must be matched with a call to secHashCleanup.
*
* Once the hash context has been setup, call secHashUpdate to add data to the
* hash calculation. Once all data has been added, call secHashFinal to get
* the resulting hash value. And finally call secHashCleanup in order to free
* any resources that has been allocated during the hash calculation.
*
* RETURNS:
* OK if the initialization is successful.
* ERROR if the hash context could not be initialized.
*
* ERRNO: N/A
*/
STATUS secHashInit
(
SEC_HASH_CTX* ctx,
const SEC_HASH_TEMPLATE* hash_template
)
{
if (!ctx || !hash_template || !(hash_template->init))
return ERROR;
ctx->hash = hash_template;
return ctx->hash->init(ctx, hash_template);
}
/*******************************************************************************
*
* secHashUpdate - Add data to a hash calculation
*
* This function adds data to a hash calculation. It can be called multiple times
* in order to add several memory segments to the calculation
*
* RETURNS: OK is the data was successfully added, ERROR otherwise.
*
* ERRNO: N/A
*/
STATUS secHashUpdate
(
SEC_HASH_CTX* ctx,
const void* data,
size_t count
)
{
if (!ctx || !(ctx->hash) || !(ctx->hash->update))
return ERROR;
return ctx->hash->update(ctx, data, count);
}
/*******************************************************************************
*
* secHashFinal - Finalize a hash calculation
*
* Return the hash of the data added by calls to secHashUpdate.
*
* RETURNS: OK if the hash value was successfully written to digest, ERROR otherwise.
*
* ERRNO: N/A
*/
STATUS secHashFinal
(
SEC_HASH_CTX* ctx,
unsigned char* digest,
unsigned int* size
)
{
if (!ctx || !(ctx->hash) || !(ctx->hash->final) || (unsigned int) ctx->hash->md_size > *size)
return ERROR;
return ctx->hash->final(ctx, digest, size);
}
/*******************************************************************************
*
* secHashCtrl - Perform an ioctl-like operation
*
* This function performs an ioctl-like operation on the hash context. This
* is included to make the hash API future proof. There are currently no ctrl
* operations defined for hash contexts.
*
* RETURNS: OK if the operation was successfully performed, ERROR otherwise.
*
* ERRNO: N/A
*/
STATUS secHashCtrl
(
struct SEC_HASH_CTX_ST* ctx,
int type,
void* arg,
unsigned int* len
)
{
if (!ctx || !ctx->hash || !ctx->hash->ctrl)
return ERROR;
return ctx->hash->ctrl(ctx, type, arg, len);
}
/*******************************************************************************
*
* secHashCopy - Copy a hash context
*
* This function makes a copy of a hash context. The hash context state is copied
* too. This means that if data is added to a hash context by calling secHashUpdate
* this data will be included in the hash calculation of the hash context copy too.
* Note that secHashCleanup must be called on the copy too.
*
* RETURNS: OK if the context was successfully copied, ERROR otherwise.
*
* ERRNO: N/A
*/
STATUS secHashCopy
(
SEC_HASH_CTX* copy,
SEC_HASH_CTX* org
)
{
if (!copy || !org || !(org->hash))
return ERROR;
if (!(org->hash->copy))
{
memset(copy, 0, sizeof(SEC_HASH_CTX));
return ERROR;
}
memcpy(copy, org, sizeof(SEC_HASH_CTX));
copy->data = 0;
return org->hash->copy(copy, org);
}
/*******************************************************************************
*
* secHashCleanup - Cleans up a hash context
*
* This function frees up any resources tied to the hash context.
*
* RETURNS: N/A
*
* ERRNO: N/A
*/
void secHashCleanup
(
SEC_HASH_CTX* ctx
)
{
if (!ctx || !(ctx->hash) || !(ctx->hash->cleanup))
return;
ctx->hash->cleanup(ctx);
}
@@ -0,0 +1,67 @@
/* secHashMd5.c - secHash template functions for MD5 */
/*
* Copyright (c) 2015, 2021 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
DESCRIPTION
secHash template functions for MD5
INCLUDE FILES: [secHash.h]
*/
/* includes */
#include <secHash.h>
/* locals */
const SEC_HASH_TEMPLATE* secHashMd5Templ = NULL;
/*******************************************************************************
*
* secHashMd5TemplateGet - Return the provider of the MD5 hash algorithm
*
* This function returns the template for the provider of the MD5 hash algorithm.
* The template is used as an argument in a call to secHashInit to setup a hashing
* context, or as an argument in a call to secHash.
*
* RETURNS: RET_DESC
*
* ERRNO: N/A
*/
const SEC_HASH_TEMPLATE* secHashMd5TemplateGet
(
void
)
{
return secHashMd5Templ;
}
/*******************************************************************************
*
* secHashMd5TemplateSet - Set the provider of the MD5 hash algorithm
*
* This function will set the provider template of the MD5 hash algorithm. This
* function is typically called during boot to register a new implementation of
* the MD5 hash algorithm. When secHashMd5TemplateSet has been called, the
* provided template will be used as return value from secHashMd5TemplateGet.
*
* RETURNS: N/A
*
* ERRNO: N/A
*/
void secHashMd5TemplateSet
(
const SEC_HASH_TEMPLATE* md5Templ
)
{
secHashMd5Templ = md5Templ;
}
@@ -0,0 +1,66 @@
/* secHashRmd.c - secHash template functions for RMD */
/*
* Copyright (c) 2015, 2021 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
DESCRIPTION
secHash template functions for RMD
INCLUDE FILES: [secHash.h]
*/
/* includes */
#include <secHash.h>
/* locals */
const SEC_HASH_TEMPLATE* secHashRmdTempl = NULL;
/*******************************************************************************
*
* secHashRmdTemplateGet - Return the provider of the RMD hash algorithm
*
* This function returns the template for the provider of the RMD hash algorithm.
* The template is used as an argument in a call to secHashInit to setup a hashing
* context, or as an argument in a call to secHash.
*
* RETURNS: RET_DESC
*
* ERRNO: N/A
*/
const SEC_HASH_TEMPLATE* secHashRmdTemplateGet
(
void
)
{
return secHashRmdTempl;
}
/*******************************************************************************
*
* secHashRmdTemplateSet - Set the provider of the RMD hash algorithm
*
* This function will set the provider template of the RMD hash algorithm. This
* function is typically called during boot to register a new implementation of
* the RMD hash algorithm. When secHashRmdTemplateSet has been called, the
* provided template will be used as return value from secHashRmdTemplateGet.
*
* RETURNS: N/A
*
* ERRNO: N/A
*/
void secHashRmdTemplateSet
(
const SEC_HASH_TEMPLATE* rmdTempl
)
{
secHashRmdTempl = rmdTempl;
}
@@ -0,0 +1,67 @@
/* secHashSha1.c - secHash template functions for SHA1 */
/*
* Copyright (c) 2015, 2021 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
DESCRIPTION
secHash template functions for SHA1
INCLUDE FILES: [secHash.h]
*/
/* includes */
#include <secHash.h>
/* locals */
const SEC_HASH_TEMPLATE* secHashSha1Templ = NULL;
/*******************************************************************************
*
* secHashSha1TemplateGet - Return the provider of the SHA1 hash algorithm
*
* This function returns the template for the provider of the SHA1 hash algorithm.
* The template is used as an argument in a call to secHashInit to setup a hashing
* context, or as an argument in a call to secHash.
*
* RETURNS: RET_DESC
*
* ERRNO: N/A
*/
const SEC_HASH_TEMPLATE* secHashSha1TemplateGet
(
void
)
{
return secHashSha1Templ;
}
/*******************************************************************************
*
* secHashSha1TemplateSet - Set the provider of the SHA1 hash algorithm
*
* This function will set the provider template of the SHA1 hash algorithm. This
* function is typically called during boot to register a new implementation of
* the SHA1 hash algorithm. When secHashSha1TemplateSet has been called, the
* provided template will be used as return value from secHashSha1TemplateGet.
*
* RETURNS: N/A
*
* ERRNO: N/A
*/
void secHashSha1TemplateSet
(
const SEC_HASH_TEMPLATE* sha1Templ
)
{
secHashSha1Templ = sha1Templ;
}
@@ -0,0 +1,67 @@
/* secHashSha256.c - secHash template functions for SHA256 */
/*
* Copyright (c) 2015, 2021 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
DESCRIPTION
secHash template functions for SHA256
INCLUDE FILES: [secHash.h]
*/
/* includes */
#include <secHash.h>
/* locals */
const SEC_HASH_TEMPLATE* secHashSha256Templ = NULL;
/*******************************************************************************
*
* secHashSha256TemplateGet - Return the provider of the SHA256 hash algorithm
*
* This function returns the template for the provider of the SHA256 hash algorithm.
* The template is used as an argument in a call to secHashInit to setup a hashing
* context, or as an argument in a call to secHash.
*
* RETURNS: RET_DESC
*
* ERRNO: N/A
*/
const SEC_HASH_TEMPLATE* secHashSha256TemplateGet
(
void
)
{
return secHashSha256Templ;
}
/*******************************************************************************
*
* secHashSha256TemplateSet - Set the provider of the SHA256 hash algorithm
*
* This function will set the provider template of the SHA256 hash algorithm. This
* function is typically called during boot to register a new implementation of
* the SHA256 hash algorithm. When secHashSha256TemplateSet has been called, the
* provided template will be used as return value from secHashSha256TemplateGet.
*
* RETURNS: N/A
*
* ERRNO: N/A
*/
void secHashSha256TemplateSet
(
const SEC_HASH_TEMPLATE* sha256Templ
)
{
secHashSha256Templ = sha256Templ;
}
@@ -0,0 +1,67 @@
/* secHashSha384.c - secHash template functions for SHA384 */
/*
* Copyright (c) 2015, 2021 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
DESCRIPTION
secHash template functions for SHA384
INCLUDE FILES: [secHash.h]
*/
/* includes */
#include <secHash.h>
/* locals */
const SEC_HASH_TEMPLATE* secHashSha384Templ = NULL;
/*******************************************************************************
*
* secHashSha384TemplateGet - Return the provider of the SHA384 hash algorithm
*
* This function returns the template for the provider of the SHA384 hash algorithm.
* The template is used as an argument in a call to secHashInit to setup a hashing
* context, or as an argument in a call to secHash.
*
* RETURNS: RET_DESC
*
* ERRNO: N/A
*/
const SEC_HASH_TEMPLATE* secHashSha384TemplateGet
(
void
)
{
return secHashSha384Templ;
}
/*******************************************************************************
*
* secHashSha384TemplateSet - Set the provider of the SHA384 hash algorithm
*
* This function will set the provider template of the SHA384 hash algorithm. This
* function is typically called during boot to register a new implementation of
* the SHA384 hash algorithm. When secHashSha384TemplateSet has been called, the
* provided template will be used as return value from secHashSha384TemplateGet.
*
* RETURNS: N/A
*
* ERRNO: N/A
*/
void secHashSha384TemplateSet
(
const SEC_HASH_TEMPLATE* sha384Templ
)
{
secHashSha384Templ = sha384Templ;
}
@@ -0,0 +1,67 @@
/* secHashSha512.c - secHash template functions for SHA512 */
/*
* Copyright (c) 2015, 2021 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
DESCRIPTION
secHash template functions for SHA512
INCLUDE FILES: [secHash.h]
*/
/* includes */
#include <secHash.h>
/* locals */
const SEC_HASH_TEMPLATE* secHashSha512Templ = NULL;
/*******************************************************************************
*
* secHashSha512TemplateGet - Return the provider of the SHA512 hash algorithm
*
* This function returns the template for the provider of the SHA512 hash algorithm.
* The template is used as an argument in a call to secHashInit to setup a hashing
* context, or as an argument in a call to secHash.
*
* RETURNS: RET_DESC
*
* ERRNO: N/A
*/
const SEC_HASH_TEMPLATE* secHashSha512TemplateGet
(
void
)
{
return secHashSha512Templ;
}
/*******************************************************************************
*
* secHashSha512TemplateSet - Set the provider of the SHA512 hash algorithm
*
* This function will set the provider template of the SHA512 hash algorithm. This
* function is typically called during boot to register a new implementation of
* the SHA512 hash algorithm. When secHashSha512TemplateSet has been called, the
* provided template will be used as return value from secHashSha512TemplateGet.
*
* RETURNS: N/A
*
* ERRNO: N/A
*/
void secHashSha512TemplateSet
(
const SEC_HASH_TEMPLATE* sha512Templ
)
{
secHashSha512Templ = sha512Templ;
}
@@ -0,0 +1,72 @@
/* secHashWhirlpool.c - secHash template functions for whirlpool */
/*
* Copyright (c) 2015, 2021 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
DESCRIPTION
secHash template functions for whirlpool.
*/
/* includes */
#include <secHash.h>
/* defines */
/* typedefs */
/* globals */
/* locals */
const SEC_HASH_TEMPLATE* secHashWhirlpoolTempl = NULL;
/* forward declarations */
/*******************************************************************************
*
* secHashWhirlpoolTemplateGet - Return the provider of the WHIRLPOOL hash algorithm
*
* This function returns the template for the provider of the WHIRLPOOL hash algorithm.
* The template is used as an argument in a call to secHashInit to setup a hashing
* context, or as an argument in a call to secHash.
*
* RETURNS: RET_DESC
*
* ERRNO: N/A
*/
const SEC_HASH_TEMPLATE* secHashWhirlpoolTemplateGet
(
void
)
{
return secHashWhirlpoolTempl;
}
/*******************************************************************************
*
* secHashWhirlpoolTemplateSet - Set the provider of the WHIRLPOOL hash algorithm
*
* This function will set the provider template of the WHIRLPOOL hash algorithm. This
* function is typically called during boot to register a new implementation of
* the WHIRLPOOL hash algorithm. When secHashWhirlpoolTemplateSet has been called, the
* provided template will be used as return value from secHashWhirlpoolTemplateGet.
*
* RETURNS: N/A
*
* ERRNO: N/A
*/
void secHashWhirlpoolTemplateSet
(
const SEC_HASH_TEMPLATE* whirlpoolTempl
)
{
secHashWhirlpoolTempl = whirlpoolTempl;
}
@@ -0,0 +1,219 @@
/* secHmac.c - VxWorks HMAC implementation */
/*
* Copyright (c) 2015, 2019-2021, 2023 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
DESCRIPTION
HMAC is a key MAC (Message Authentication Code), used for message authentication.
The HMAC API can be used to calculate an HMAC on a consecutive memory area. If the
memory is divided into multiple chunks secHmacInit, secHmacUpdate and secHmacUpdate
must be used.
INCLUDE FILES: secHmac.h
SEE ALSO
\tb [VxWorks Cryptography Libraries Programmer's Guide](https://docs.windriver.com/bundle/vxworks_cryptography_libraries_programmers_guide_@vx_release/page/sgr1441901569970.html),
\tb [RFC2104](https://tools.ietf.org/html/rfc2104),
\tb [RFC2202](https://tools.ietf.org/html/rfc2202)
*/
/* includes */
#include <vxWorks.h>
#include <string.h>
#include <secHash.h>
#include <secHmac.h>
#include <vsbConfig.h>
#ifdef _WRS_CONFIG_OPENSSL_FIPSMODULE
#include <openssl/provider.h>
#endif
/* defines */
/* typedefs */
/* globals */
/* locals */
/* forward declarations */
/*******************************************************************************
*
* secHmacInit - Initialize a SEC_HMAC_CTX
*
* Initialize a SEC_HMAC_CTX. Must be called before secHmacUpdate and secHmacFinal can be called.
*
* RETURNS: OK if successful, ERROR otherwise
*
*/
STATUS secHmacInit
(
SEC_HMAC_CTX* ctx,
const unsigned char* key,
int keyLen,
const SEC_HASH_TEMPLATE* hashTemplate)
{
unsigned char tmpKey[64];
int i;
unsigned int digestLen = 0;
if (!ctx || !key || !hashTemplate)
return ERROR;
memset(ctx, 0, sizeof(SEC_HMAC_CTX));
#ifdef _WRS_CONFIG_OPENSSL_FIPSMODULE
/* MD5 and RMD cannot be used in FIPS 140-2 mode */
if (OSSL_PROVIDER_available(NULL, "fips"))
{
if (hashTemplate->type == SEC_HASH_ID_MD5 || hashTemplate->type == SEC_HASH_ID_RMD)
return ERROR;
}
#endif
/* if key is longer than the block size of the hash reset it to key=HASH(key) */
if (keyLen > hashTemplate->blockSize)
{
digestLen = (unsigned int) hashTemplate->md_size;
(void)secHashInit(&ctx->hashCtx, hashTemplate);
(void)secHashUpdate(&ctx->hashCtx, key, (size_t) keyLen);
(void)secHashFinal(&ctx->hashCtx, tmpKey, &digestLen);
secHashCleanup(&ctx->hashCtx);
key = tmpKey;
keyLen = (int) digestLen;
}
ctx->keyLen = (unsigned int) keyLen;
memcpy(ctx->k_ipad, key, (size_t) keyLen);
memcpy(ctx->k_opad, key, (size_t) keyLen);
/* XOR key with ipad and opad values */
for (i=0; i<hashTemplate->blockSize; i++) {
ctx->k_ipad[i] ^= 0x36;
ctx->k_opad[i] ^= 0x5c;
}
if (secHashInit(&ctx->hashCtx, hashTemplate) != OK ||
secHashUpdate(&ctx->hashCtx, ctx->k_ipad, (size_t) hashTemplate->blockSize) != OK)
{
return ERROR;
}
return OK;
}
/*******************************************************************************
*
* secHmacUpdate - add data to an HMAC calcuation
*
* secHmacUpdate can be called repeatedly in order to add multiple chunks of data
* to an HMAC calculation.
*
* RETURNS: OK if successful, ERROR otherwise.
*
*/
STATUS secHmacUpdate
(
SEC_HMAC_CTX* ctx,
const unsigned char* data,
unsigned int dataLen
)
{
if (!ctx || !data)
return ERROR;
return secHashUpdate(&ctx->hashCtx, data, dataLen);
}
/*******************************************************************************
*
* secHmacFinal - Finalize an HMAC calculation
*
* Finalize an HMAC calculation. hmacLen must be at least as long as the hash
* output length.
*
* RETURNS: OK if successful, ERROR otherwise
*
*/
STATUS secHmacFinal
(
SEC_HMAC_CTX* ctx,
unsigned char* hmac,
unsigned int* hmacLen
)
{
unsigned char tmpBuf[64];
unsigned int tmpLen = sizeof(tmpBuf);
if (!ctx || !hmac || !hmacLen || *hmacLen < (unsigned int) ctx->hashCtx.hash->md_size)
return ERROR;
if (secHashFinal(&ctx->hashCtx, tmpBuf, &tmpLen) != OK)
return ERROR;
secHashCleanup(&ctx->hashCtx);
if (secHashInit(&(ctx->hashCtx), ctx->hashCtx.hash) != OK ||
secHashUpdate(&(ctx->hashCtx), ctx->k_opad, (size_t) ctx->hashCtx.hash->blockSize) != OK ||
secHashUpdate(&(ctx->hashCtx), tmpBuf, (size_t) tmpLen) ||
secHashFinal(&(ctx->hashCtx), hmac, hmacLen) != OK)
{
return ERROR;
}
return OK;
}
void secHmacCleanup
(
SEC_HMAC_CTX* ctx
)
{
secHashCleanup(&ctx->hashCtx);
}
/*******************************************************************************
*
* secHmac - Calculate an HMAC
*
* This function calculates an HMAC on a consecutive memory area
*
* RETURNS: OK if succesful, ERROR otherwise
*
*/
STATUS secHmac
(
const unsigned char* key,
int keyLen,
unsigned char* data,
unsigned int dataLen,
unsigned char* hmac,
unsigned int* hmacLen,
const SEC_HASH_TEMPLATE* hashTemplate)
{
SEC_HMAC_CTX ctx;
if (secHmacInit(&ctx, key, keyLen, hashTemplate) != OK
|| secHmacUpdate(&ctx, data, dataLen)
|| secHmacFinal(&ctx, hmac, hmacLen) != OK)
{
secHmacCleanup(&ctx);
return ERROR;
}
secHmacCleanup(&ctx);
return OK;
}
@@ -0,0 +1,156 @@
/* secPbkdf2.c - PKCS5 Password-based key derivation function 2.0, RFC 2898 */
/*
* Copyright (c) 2015, 2019-2021 Wind River Systems, Inc.
*
* The right to copy, distribute, modify, or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
DESCRIPTION
This module implements PKCS5 Password-based key derivation function 2.0, RFC 2898
INCLUDE FILES: secPbkdf2.h
SEE ALSO
\tb [VxWorks Cryptography Libraries Programmer's Guide](https://docs.windriver.com/bundle/vxworks_cryptography_libraries_programmers_guide_@vx_release/page/sgr1441901569970.html),
\tb [RFC2898](https://tools.ietf.org/html/rfc2898)
*/
/* includes */
#include <vxWorks.h>
#include <string.h>
#include <secHash.h>
#include <secHmac.h>
#include <secPbkdf2.h>
/* defines */
/* typedefs */
/* globals */
/* locals */
/* forward declarations */
static STATUS F
(
const char* pw,
int pwLen,
const unsigned char* salt,
int saltLen,
int c,
const unsigned char* i,
const SEC_HASH_TEMPLATE* hash,
unsigned char* out
)
{
unsigned char block[64];
SEC_HMAC_CTX hmacCtx;
int iter;
unsigned int j;
unsigned int hmacLen = (unsigned int) hash->md_size;
if ((size_t) hash->md_size > sizeof(block))
return ERROR;
if (secHmacInit(&hmacCtx, (const unsigned char*)pw, pwLen, hash) != OK)
return ERROR;
if (secHmacUpdate(&hmacCtx, salt, (unsigned int) saltLen) != OK ||
secHmacUpdate(&hmacCtx, i, 4) != OK ||
secHmacFinal(&hmacCtx, block, &hmacLen) != OK)
{
secHmacCleanup(&hmacCtx);
return ERROR;
}
secHmacCleanup(&hmacCtx);
memcpy(out, block, hmacLen);
for (iter=1; iter<c; iter++)
{
if (secHmac((const unsigned char*)pw, pwLen, block, hmacLen, block, &hmacLen, hash) != OK)
return ERROR;
for (j=0; j<hmacLen; j++)
out[j] ^= block[j];
}
return OK;
}
/*******************************************************************************
*
* secPbkdf2Hmac - PKCS5 Password-based key derivation function 2.0
*
* PKCS5 Password-based key derivation function 2.0, RFC 2898
*
* ARGUMENTS
* \is
* \i pw
* Password used to to generate keying material
* \i pwLen
* Length of the pw argument
* \i salt
* Pointer to salt
* \i saltLen
* Length of salt argument
* \i c
* Iteration count
* \i hash
* template for the hash function to use for the HMAC operations. This is typically
* the return value of a secHash<alg>TempateGet function, e.g. secHashSha1TemplateGet()
* \ie
*
* RETURNS: OK on success, ERROR otherwise
*
*/
STATUS secPbkdf2Hmac
(
const char *pw,
int pwLen,
const unsigned char *salt,
int saltLen,
int c,
const SEC_HASH_TEMPLATE *hash,
int keyLen,
unsigned char *key
)
{
unsigned char lastBlock[64];
int l;
int r;
int j, k;
unsigned char i[4] = {0, 0, 0, 1};
if (!pw || !salt || !hash || (size_t)hash->md_size > sizeof(lastBlock) || !key)
return ERROR;
l = keyLen/hash->md_size;
r = keyLen % hash->md_size;
for (j=0; j<l; j++)
{
if (F(pw, pwLen, salt, saltLen, c, i, hash, key) != OK)
return ERROR;
key += hash->md_size;
for (k=3; k>0; k--)
{
i[k]++;
if (i[k])
break;
}
}
if (r)
{
if (F(pw, pwLen, salt, saltLen, c, i, hash, lastBlock) != OK)
return ERROR;
memcpy(key, lastBlock, (size_t)r);
}
return OK;
}