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:
committed by
neelimap
co-authored by
neelimap
parent
368226261b
commit
122392cfc0
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user