StarlingX open source release updates

Signed-off-by: Dean Troyer <dtroyer@gmail.com>
This commit is contained in:
Dean Troyer 2018-05-30 16:17:22 -07:00
parent 948d42b03b
commit 2203ceba11
15 changed files with 2353 additions and 0 deletions

202
security/stx-ssl/LICENSE Normal file
View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1,2 @@
COPY_LIST="$PKG_BASE/files/* $PKG_BASE/LICENSE $PKG_BASE/server-csr.conf"
TIS_PATCH_VER=13

View File

@ -0,0 +1,41 @@
Summary: wrs-ssl version 1.0.0-r2
Name: wrs-ssl
Version: 1.0.0
Release: %{tis_patch_ver}%{?_tis_dist}
License: Apache-2.0
Group: base
Packager: Wind River <info@windriver.com>
URL: unknown
BuildRequires: openssl
Source0: LICENSE
Source1: server-csr.conf
Source2: tpmdevice-setup
%description
Wind River Security
%install
rm -rf $RPM_BUILD_ROOT
RPM_BUILD_DIR_PKG="%{name}-%{version}"
mkdir -p $RPM_BUILD_DIR_PKG
CSRCONF="$RPM_BUILD_DIR_PKG/server-csr.conf"
PEMFILE="$RPM_BUILD_DIR_PKG/server-cert.pem"
cp %{SOURCE1} $CSRCONF
# generate a self signed default certificate
/usr/bin/openssl req -new -x509 -sha256 -keyout $PEMFILE -out $PEMFILE -days 365 -nodes -config $CSRCONF
mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/ssl/private
install -m 400 $PEMFILE $RPM_BUILD_ROOT/%{_sysconfdir}/ssl/private/server-cert.pem
mkdir -p $RPM_BUILD_ROOT/%{_sbindir}
install -m 700 %{SOURCE2} $RPM_BUILD_ROOT/%{_sbindir}/tpmdevice-setup
mkdir -p $RPM_BUILD_ROOT/%{_defaultdocdir}/%{name}-%{version}
install -m 644 %{SOURCE0} $RPM_BUILD_ROOT/%{_defaultdocdir}/%{name}-%{version}
%files
%defattr(-,root,root,-)
%{_sysconfdir}/*
%{_sbindir}/*
%{_defaultdocdir}/%{name}-%{version}

View File

@ -0,0 +1,160 @@
#!/bin/bash
#
# Copyright (c) 2013-2017 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
# TPM setup (both active controller and remote)
CERTIFICATE_FILE="server-cert.pem"
LOGFILE="/etc/ssl/private/.install.log"
ORIGINAL_KEY=$1
TPM_OBJECT_CONTEXT=$2
PUBLIC_KEY=$3
TPM_KEY_HIERARCHY_HANDLE=0x81010002
if [ -z "$ORIGINAL_KEY" ] || [ -z "$TPM_OBJECT_CONTEXT" ] || [ -z "$PUBLIC_KEY" ]; then
echo "ERROR: Missing required parameters"
echo "USAGE: $0 <privatekey> <tpm_context> <publickey>"
exit 1
fi
CERTIFICATE_DIR=$(dirname "${ORIGINAL_KEY}")
export TPM_DATA_DIR=$CERTIFICATE_DIR
# TPM specific environment
TPM_OBJECT_NAME="$CERTIFICATE_DIR/key.blob.name"
RESOURCEMGR_DEFAULT_PORT="2323"
### Helper functions ###
# Echo's an error and exits with provided error code
# Input : error message ($1), ret code ($2)
# Output : None
# Note : If no retcode is provided, exits with 1
error_exit () {
echo "$1"
# remove previous object context
rm -f $TPM_OBJECT_CONTEXT &> /dev/null
exit "${2:-1}"
}
# func: checkTPMTools
# check if the appropriate TPM2.0-tools are installed
#
# Input : None
# Output : None
checkTPMTools () {
declare -a helper_scripts=("tss2_createprimary"
"tss2_importpem"
"tss2_getcapability"
"tss2_load"
"tss2_contextsave"
"tss2_evictcontrol"
"tss2_flushcontext"
"create_tpm2_key"
"resourcemgr")
for src in "${helper_scripts[@]}"; do
if ! type "$src" &>/dev/null; then
error_exit "ERROR: Cannot find $src. Needed for TPM configuration"
fi
done
}
startResourceMgr () {
resourcemgr &>> $LOGFILE 2>&1 &
# ensure the resourcemgr is started
for i in {1..5}
do
sleep 0.5
MGR_RUNNING=`pidof resourcemgr`
if [ ! -z $MGR_RUNNING ]; then
break
fi
done
[ ! -z $MGR_RUNNING ] || error_exit "Unable to start TPM resourcemgr"
# check to see if the resourcemgr port is open
IS_OPEN=0
for i in {1..5}
do
sleep 0.5
_test=`netstat -an | grep $RESOURCEMGR_DEFAULT_PORT | grep -i listen`
if [ ! -z "$_test" ]; then
IS_OPEN=1
break
fi
done
[ $IS_OPEN -ne 0 ] || error_exit "Unable to initialize resourcemgr"
}
stopResourceMgr () {
# Kill any previous instances of resourcemgr
pkill -c -TERM resourcemgr &> /dev/null 2>&1
}
### Main ###
# remove previous object context
rm -f $TPM_OBJECT_CONTEXT &> /dev/null
rm -f $CERTIFICATE_DIR/*.bin &> /dev/null
tpmCheck=`lsmod | grep "tpm" -c`
[ "$tpmCheck" -ne 0 ] || error_exit "TPM Kernel Module not found. Check BIOS/Kernel configuration"
# Ensure that the appropriate TPM tool utilities are
# installed on the system
checkTPMTools
# Confirm that this is a TPM 2.0 device
TPM_VERSION=`tss2_getcapability -cap 6 | grep TPM_PT_FAMILY_INDICATOR | awk '{print $4}' | xxd -r -p`
if [ "$TPM_VERSION" != "2.0" ]; then
error_exit "ERROR: TPM Device is not version 2.0 compatible"
fi
# Start the Intel ResourceMgr to clear the NV
# as well as all stale transient handles in
# the endorsement hierarchy.
# Since ResourceMgr has a number of stability,
# and security issues, we will stop it after it
# initializes the NV and Handle space
startResourceMgr
stopResourceMgr
# Create the Endorsement Primary Key hierarchy which will be used
# for wrapping the private key. Use RSA as the primary key encryption
# and SHA 256 for hashing. Allow TPM to output the object
# handle as a file context
PRIMARY_HANDLE=`tss2_createprimary -hi e -rsa -halg sha256 | grep "Handle" | awk '{print $2}'`
[ ! -z "$PRIMARY_HANDLE" ] || error_exit "Unable to create TPM Key Hierarchy"
PRIMARY_HANDLE="0x$PRIMARY_HANDLE"
# The object context will be lost over node reboots, and needs to
# be persistently stored in TPM NV.
# evict the persistent handle if it exists previously
tss2_evictcontrol -hi o -ho $TPM_KEY_HIERARCHY_HANDLE -hp $TPM_KEY_HIERARCHY_HANDLE
tss2_evictcontrol -hi o -ho $PRIMARY_HANDLE -hp $TPM_KEY_HIERARCHY_HANDLE &>> $LOGFILE
[ $? -eq 0 ] || error_exit "Unable to persist Key Hierarchy in TPM memory"
tss2_flushcontext -ha $PRIMARY_HANDLE
# wrap the original private key in TPM's Endorsement key hierarchy
# this will generate a TSS key blob in ASN 1 encoding
create_tpm2_key -p $TPM_KEY_HIERARCHY_HANDLE -w $ORIGINAL_KEY $TPM_OBJECT_CONTEXT &>> $LOGFILE
[ $? -eq 0 ] || error_exit "Unable to wrap provided private key into TPM Key Hierarchy"
# the apps will also need to the public key, place it in
# the certificate dirpath
mv $PUBLIC_KEY $CERTIFICATE_DIR/$CERTIFICATE_FILE
# ensure that the TPM object and the public cert are only readable by root
chown root $CERTIFICATE_DIR/$CERTIFICATE_FILE $TPM_OBJECT_CONTEXT
chmod 0600 $CERTIFICATE_DIR/$CERTIFICATE_FILE $TPM_OBJECT_CONTEXT
# remove all sysinv key copy artifacts
rm -f $ORIGINAL_KEY "${ORIGINAL_KEY}.sysinv" "${PUBLIC_KEY}.sysinv" &> /dev/null
exit 0

View File

@ -0,0 +1,13 @@
[ req ]
default_bits = 1024
distinguished_name = req_distinguished_name
prompt = no
[ req_distinguished_name ]
C = CA
ST = Ontario
L = Ottawa
O = Wind River Inc.
OU = Carrier Grade Communications Server
CN = *.wrs.com

View File

@ -0,0 +1,14 @@
Metadata-Version: 1.1
Name: tpm2-openssl-engine
Version: 1.0
Summary: TPM 2.0 Openssl Engine
Home-page:
Author: Windriver
Author-email: info@windriver.com
License: openssl
Description: Titanium Control's TPM 2.0 OpenSSL Engine. Leveraged by
Titanium applications to provide secure TLS Decryption and Signing
capabilities to Titanium host applications.
Platform: UNKNOWN

View File

@ -0,0 +1,2 @@
SRC_DIR="tpm2-openssl-engine"
TIS_PATCH_VER=2

View File

@ -0,0 +1,39 @@
Name: tpm2-openssl-engine
Version: 1.0
Release: %{tis_patch_ver}%{?_tis_dist}
Summary: TPM 2.0 Openssl Engine
License: openssl
Group: base
Packager: Wind River <info@windriver.com>
URL: unknown
Source0: %{name}-%{version}.tar.gz
BuildRequires: openssl-devel
BuildRequires: openssl
BuildRequires: tss2-devel
Requires: tss2
%description
TPM 2.0 OpenSSL engine. Leveraged by applications
to provide secure TLS Decryption and Signing capabilities
%prep
%setup -q
%build
make %{?_smp_mflags}
%install
make install ENGINEDIR=%{buildroot}/%{_libdir}/openssl/engines UTILDIR=%{buildroot}/usr/sbin
%files
%license LICENSE
%defattr(-,root,root,-)
%{_libdir}/openssl/engines/libtpm2.so
/usr/sbin/create_tpm2_key

View File

@ -0,0 +1,57 @@
OpenSSL License
====================================================================
Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. All advertising materials mentioning features or use of this
software must display the following acknowledgment:
"This product includes software developed by the OpenSSL Project
for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
endorse or promote products derived from this software without
prior written permission. For written permission, please contact
openssl-core@openssl.org.
5. Products derived from this software may not be called "OpenSSL"
nor may "OpenSSL" appear in their names without prior written
permission of the OpenSSL Project.
6. Redistributions of any form whatsoever must retain the following
acknowledgment:
"This product includes software developed by the OpenSSL Project
for use in the OpenSSL Toolkit (http://www.openssl.org/)"
THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.
====================================================================
This product includes cryptographic software written by Eric Young
(eay@cryptsoft.com). This product includes software written by Tim
Hudson (tjh@cryptsoft.com).
This product is inspired by the original TPM 1.2 openssl engine written
by Kent Yoder <kyoder@users.sf.net> for the Trousers Project. This product
includes TPM key blob ASN-1 encoding scheme from James Bottomley
<james.bottomley@HansenPartnership.com>

View File

@ -0,0 +1,54 @@
#
# Copyright (c) 2013-2017 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
#### Installation options
ENGINEDIR=
UTILDIR=
#### Toolchain options
CC = gcc
LD = $(CC)
#### Debug flags (typically "-g").
# Those flags only feed CFLAGS so it is not mandatory to use this form.
DEBUG_CFLAGS = -g -O2 -Werror -Wno-unused-parameter -Wno-missing-braces
#### Compiler-specific flags that may be used to disable some negative over-
# optimization or to silence some warnings. -fno-strict-aliasing is needed with
# gcc >= 4.4.
SPEC_CFLAGS = -fno-strict-aliasing
#### Common CFLAGS
CFLAGS = $(DEBUG_CFLAGS) $(SPEC_CFLAGS)
#### Common LDFLAGS
LDFLAGS = -g
DYNAMIC_ENGINE=libtpm2.so
UTIL=create_tpm2_key
INCLUDES+=-I${SYSTEM_DIR}/usr/include/
LDFLAGS +=-lcrypto -lc -ltss
SRCS += e_tpm2.c e_tpm2_err.c
HEADERS += e_tpm2.h
OBJS = $(SRCS:.c=.o)
all: $(DYNAMIC_ENGINE) ${UTIL}
${UTIL}: $(OBJS)
$(CC) -Wall ${CFLAGS} ${INCLUDES} create_tpm2_key.c ${LDFLAGS} -o ${UTIL}
$(DYNAMIC_ENGINE): $(OBJS)
$(CC) -Wall ${CFLAGS} ${INCLUDES} ${LDFLAGS} -fPIC -c ${SRCS}
$(CC) -shared -Wl,-soname,${DYNAMIC_ENGINE} ${LDFLAGS} -o ${DYNAMIC_ENGINE} $(OBJS)
install: all
install -D -m 755 ${DYNAMIC_ENGINE} ${ENGINEDIR}/${DYNAMIC_ENGINE}
install -D -m 755 ${UTIL} ${UTILDIR}/${UTIL}
clean:
$(RM) *.o *.so *.so.0

View File

@ -0,0 +1,479 @@
/*
* Copyright (c) 2017 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
*/
/* ====================================================================
*
* Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
* This product is inspired by the original TPM 1.2 openssl engine written
* by Kent Yoder <kyoder@users.sf.net> for the Trousers Project. This product
* includes TPM key blob ASN-1 encoding scheme from James Bottomley
* <james.bottomley@HansenPartnership.com>
*
*/
#include <stdio.h>
#include <getopt.h>
#include <string.h>
#include <strings.h>
#include <errno.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/rand.h>
#include <tss2/tss.h>
#include <tss2/tssutils.h>
#include <tss2/tssmarshal.h>
#include <tss2/tssresponsecode.h>
#include "tpm2-asn.h"
static struct option long_options[] = {
{"auth", 0, 0, 'a'},
{"help", 0, 0, 'h'},
{"name-scheme", 1, 0, 'n'},
{"parent-handle", 1, 0, 'p'},
{"wrap", 1, 0, 'w'},
{0, 0, 0, 0}
};
static TPM_ALG_ID name_alg = TPM_ALG_SHA256;
static int name_alg_size = SHA256_DIGEST_SIZE;
void
usage(char *argv0)
{
fprintf(stderr, "\t%s: create a TPM key and write it to disk\n"
"\tusage: %s [options] <filename>\n\n"
"\tOptions:\n"
"\t\t-a|--auth require a password for the key [NO]\n"
"\t\t-h|--help print this help message\n"
"\t\t-n|--name-scheme name algorithm to use sha1 [sha256] sha384 sha512\n"
"\t\t-p|--parent-handle persistent handle of parent key\n"
"\t\t-w|--wrap [file] wrap an existing openssl PEM key\n",
argv0, argv0);
exit(-1);
}
void tpm2_error(TPM_RC rc, const char *reason)
{
const char *msg, *submsg, *num;
fprintf(stderr, "%s failed with %d\n", reason, rc);
TSS_ResponseCode_toString(&msg, &submsg, &num, rc);
fprintf(stderr, "%s%s%s\n", msg, submsg, num);
}
void
openssl_print_errors()
{
ERR_load_ERR_strings();
ERR_load_crypto_strings();
ERR_print_errors_fp(stderr);
}
int
openssl_write_tpmfile(const char *file, BYTE *pubkey, int pubkey_len,
BYTE *privkey, int privkey_len, int empty_auth,
TPM_HANDLE parent)
{
TSSLOADABLE tssl;
BIO *outb;
/* clear structure so as not to have to set optional parameters */
memset(&tssl, 0, sizeof(tssl));
if ((outb = BIO_new_file(file, "w")) == NULL) {
fprintf(stderr, "Error opening file for write: %s\n", file);
return 1;
}
tssl.type = OBJ_txt2obj(OID_loadableKey, 1);
tssl.emptyAuth = empty_auth;
if ((parent & 0xff000000) == 0x81000000) {
tssl.parent = ASN1_INTEGER_new();
ASN1_INTEGER_set(tssl.parent, parent);
}
tssl.pubkey = ASN1_OCTET_STRING_new();
ASN1_STRING_set(tssl.pubkey, pubkey, pubkey_len);
tssl.privkey = ASN1_OCTET_STRING_new();
ASN1_STRING_set(tssl.privkey, privkey, privkey_len);
PEM_write_bio_TSSLOADABLE(outb, &tssl);
BIO_free(outb);
return 0;
}
EVP_PKEY *
openssl_read_key(char *filename)
{
BIO *b = NULL;
EVP_PKEY *pkey;
b = BIO_new_file(filename, "r");
if (b == NULL) {
fprintf(stderr, "Error opening file for read: %s\n", filename);
return NULL;
}
if ((pkey = PEM_read_bio_PrivateKey(b, NULL, PEM_def_callback, NULL)) == NULL) {
fprintf(stderr, "Reading key %s from disk failed.\n", filename);
openssl_print_errors();
}
BIO_free(b);
return pkey;
}
void tpm2_public_template_rsa(TPMT_PUBLIC *pub)
{
pub->type = TPM_ALG_RSA;
pub->nameAlg = name_alg;
/* note: all our keys are decrypt only. This is because
* we use the TPM2_RSA_Decrypt operation for both signing
* and decryption (see e_tpm2.c for details) */
pub->objectAttributes.val = TPMA_OBJECT_NODA |
TPMA_OBJECT_DECRYPT |
TPMA_OBJECT_SIGN |
TPMA_OBJECT_USERWITHAUTH;
pub->authPolicy.t.size = 0;
pub->parameters.rsaDetail.symmetric.algorithm = TPM_ALG_NULL;
pub->parameters.rsaDetail.scheme.scheme = TPM_ALG_NULL;
}
TPM_RC openssl_to_tpm_public_rsa(TPMT_PUBLIC *pub, EVP_PKEY *pkey)
{
RSA *rsa = EVP_PKEY_get1_RSA(pkey);
BIGNUM *n, *e;
int size = RSA_size(rsa);
unsigned long exp;
if (size > MAX_RSA_KEY_BYTES)
return TPM_RC_KEY_SIZE;
#if OPENSSL_VERSION_NUMBER < 0x10100000
n = rsa->n;
e = rsa->e;
#else
RSA_get0_key(&n, &e, NULL);
#endif
exp = BN_get_word(e);
/* TPM limitations means exponents must be under a word in size */
if (exp == 0xffffffffL)
return TPM_RC_KEY_SIZE;
tpm2_public_template_rsa(pub);
pub->parameters.rsaDetail.keyBits = size*8;
if (exp == 0x10001)
pub->parameters.rsaDetail.exponent = 0;
else
pub->parameters.rsaDetail.exponent = exp;
pub->unique.rsa.t.size = BN_bn2bin(n, pub->unique.rsa.t.buffer);
return 0;
}
TPM_RC openssl_to_tpm_public(TPM2B_PUBLIC *pub, EVP_PKEY *pkey)
{
TPMT_PUBLIC *tpub = &pub->publicArea;
pub->size = sizeof(*pub);
switch (EVP_PKEY_type(pkey->type)) {
case EVP_PKEY_RSA:
return openssl_to_tpm_public_rsa(tpub, pkey);
default:
break;
}
return TPM_RC_ASYMMETRIC;
}
TPM_RC openssl_to_tpm_private_rsa(TPMT_SENSITIVE *s, EVP_PKEY *pkey)
{
BIGNUM *q;
TPM2B_PRIVATE_KEY_RSA *t2brsa = &s->sensitive.rsa;
RSA *rsa = EVP_PKEY_get1_RSA(pkey);
#if OPENSSL_VERSION_NUMBER < 0x10100000
q = rsa->q;
#else
BIGNUM *p;
RSA_get0_factors(rsa, &p, &q);
#endif
if (!q)
return TPM_RC_ASYMMETRIC;
s->sensitiveType = TPM_ALG_RSA;
s->seedValue.b.size = 0;
t2brsa->t.size = BN_bn2bin(q, t2brsa->t.buffer);
return 0;
}
TPM_RC openssl_to_tpm_private(TPMT_SENSITIVE *priv, EVP_PKEY *pkey)
{
switch (EVP_PKEY_type(pkey->type)) {
case EVP_PKEY_RSA:
return openssl_to_tpm_private_rsa(priv, pkey);
default:
break;
}
return TPM_RC_ASYMMETRIC;
}
TPM_RC wrap_key(TPM2B_PRIVATE *priv, const char *password, EVP_PKEY *pkey)
{
TPMT_SENSITIVE s;
TPM2B_SENSITIVE b;
BYTE *buf;
int32_t size;
TPM_RC rc;
memset(&b, 0, sizeof(b));
memset(&s, 0, sizeof(s));
openssl_to_tpm_private(&s, pkey);
if (password) {
int len = strlen(password);
memcpy(s.authValue.b.buffer, password, len);
s.authValue.b.size = len;
} else {
s.authValue.b.size = 0;
}
size = sizeof(s);
buf = b.b.buffer;
rc = TSS_TPMT_SENSITIVE_Marshal(&s, &b.b.size, &buf, &size);
if (rc)
tpm2_error(rc, "TSS_TPMT_SENSITIVE_Marshal");
size = sizeof(*priv);
buf = priv->b.buffer;
priv->b.size = 0;
/* no encryption means innerIntegrity and outerIntegrity are
* absent, so the TPM2B_PRIVATE is a TPMT_SENSITIVE*/
rc = TSS_TPM2B_PRIVATE_Marshal((TPM2B_PRIVATE *)&b, &priv->b.size, &buf, &size);
if (rc)
tpm2_error(rc, "TSS_TPM2B_PRIVATE_Marshal");
return TPM_RC_ASYMMETRIC;
}
int main(int argc, char **argv)
{
char *filename, c, *wrap = NULL, *auth = NULL;
int option_index;
const char *reason;
TSS_CONTEXT *tssContext = NULL;
TPM_HANDLE parent = 0;
TPM_RC rc = 0;
BYTE pubkey[sizeof(TPM2B_PUBLIC)],privkey[sizeof(TPM2B_PRIVATE)], *buffer;
uint16_t pubkey_len, privkey_len;
int32_t size = 0;
TPM2B_PUBLIC *pub;
TPM2B_PRIVATE *priv;
while (1) {
option_index = 0;
c = getopt_long(argc, argv, "n:ap:hw:",
long_options, &option_index);
if (c == -1)
break;
switch (c) {
case 'a':
auth = malloc(128);
break;
case 'h':
usage(argv[0]);
break;
case 'n':
if (!strcasecmp("sha1", optarg)) {
name_alg = TPM_ALG_SHA1;
name_alg_size = SHA1_DIGEST_SIZE;
} else if (strcasecmp("sha256", optarg)) {
/* default, do nothing */
} else if (strcasecmp("sha384", optarg)) {
name_alg = TPM_ALG_SHA384;
name_alg_size = SHA384_DIGEST_SIZE;
#ifdef TPM_ALG_SHA512
} else if (strcasecmp("sha512", optarg)) {
name_alg = TPM_ALG_SHA512;
name_alg_size = SHA512_DIGEST_SIZE;
#endif
} else {
usage(argv[0]);
}
break;
case 'p':
parent = strtol(optarg, NULL, 16);
break;
case 'w':
wrap = optarg;
break;
default:
usage(argv[0]);
break;
}
}
filename = argv[argc - 1];
if (argc < 2)
usage(argv[0]);
if (!wrap) {
fprintf(stderr, "wrap is a compulsory option\n");
usage(argv[0]);
}
if (!parent) {
fprintf(stderr, "parent handle is a compulsory option\n");
usage(argv[0]);
}
if (parent && (parent & 0xff000000) != 0x81000000) {
fprintf(stderr, "you must specify a persistent parent handle\n");
usage(argv[0]);
}
if (auth) {
if (EVP_read_pw_string(auth, 128, "Enter TPM key authority: ", 1)) {
fprintf(stderr, "Passwords do not match\n");
exit(1);
}
}
rc = TSS_Create(&tssContext);
if (rc) {
reason = "TSS_Create";
goto out_err;
}
/*
* avoid using the device TCTI as that will bind
* exclusively to the TPM device. Instead
* use the Kernel TPM Resource Manager as that
* allows concurrent access
*
* N.B: This assumes that the kernel-modules-tpm
* pkg is installed with the modified tpm_crb KLM
*/
rc = TSS_SetProperty(tssContext, TPM_DEVICE, "/dev/tpmrm0");
if (rc) {
reason = "TSS_SetProperty: TPM_USE_RESOURCE_MANAGER";
goto out_err;
}
if (wrap) {
Import_In iin;
Import_Out iout;
EVP_PKEY *pkey;
/* may be needed to decrypt the key */
OpenSSL_add_all_ciphers();
pkey = openssl_read_key(wrap);
if (!pkey) {
reason = "unable to read key";
goto out_delete;
}
iin.parentHandle = parent;
iin.encryptionKey.t.size = 0;
openssl_to_tpm_public(&iin.objectPublic, pkey);
/* set random iin.symSeed */
iin.inSymSeed.t.size = 0;
iin.symmetricAlg.algorithm = TPM_ALG_NULL;
wrap_key(&iin.duplicate, auth, pkey);
openssl_to_tpm_public(&iin.objectPublic, pkey);
rc = TSS_Execute(tssContext,
(RESPONSE_PARAMETERS *)&iout,
(COMMAND_PARAMETERS *)&iin,
NULL,
TPM_CC_Import,
TPM_RS_PW, NULL, 0,
TPM_RH_NULL, NULL, 0,
TPM_RH_NULL, NULL, 0,
TPM_RH_NULL, NULL, 0);
if (rc) {
reason = "TPM2_Import";
goto out_flush;
}
pub = &iin.objectPublic;
priv = &iout.outPrivate;
}
buffer = pubkey;
pubkey_len = 0;
size = sizeof(pubkey);
TSS_TPM2B_PUBLIC_Marshal(pub, &pubkey_len, &buffer, &size);
buffer = privkey;
privkey_len = 0;
size = sizeof(privkey);
TSS_TPM2B_PRIVATE_Marshal(priv, &privkey_len, &buffer, &size);
openssl_write_tpmfile(filename, pubkey, pubkey_len, privkey, privkey_len, auth == NULL, parent);
TSS_Delete(tssContext);
exit(0);
out_flush:
out_delete:
TSS_Delete(tssContext);
out_err:
tpm2_error(rc, reason);
exit(1);
}

View File

@ -0,0 +1,852 @@
/*
* Copyright (c) 2017 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
*/
/* ====================================================================
* Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
* This product is inspired by the original TPM 1.2 openssl engine written
* by Kent Yoder <kyoder@users.sf.net> for the Trousers Project. This product
* includes TPM key blob ASN-1 encoding scheme from James Bottomley
* <james.bottomley@HansenPartnership.com>
*
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <openssl/crypto.h>
#include <openssl/dso.h>
#include <openssl/engine.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/sha.h>
#include <openssl/bn.h>
#include <openssl/asn1.h>
#include <openssl/pem.h>
#include "e_tpm2.h"
#include "tpm2-asn.h"
//IMPLEMENT_ASN1_FUNCTIONS(TSSLOADABLE)
/* IBM TSS2 library functions */
static const char *TPM_F_File_ReadStructure = "TSS_File_ReadStructure";
static const char *TPM_F_Context_Create = "TSS_Create";
static const char *TPM_F_Context_Close = "TSS_Delete";
static const char *TPM_F_TPM_Execute = "TSS_Execute";
static const char *TPM_F_Hash_Generate = "TSS_Hash_Generate";
static const char *TPM_F_Structure_Marshal = "TSS_Structure_Marshal";
static const char *TPM_F_PrivateKey_Unmarshal = "TPM2B_PRIVATE_Unmarshal";
static const char *TPM_F_PublicKey_Unmarshal = "TPM2B_PUBLIC_Unmarshal";
static const char *TPM_F_Set_Property = "TSS_SetProperty";
/* engine specific functions */
static int tpm_engine_destroy(ENGINE *);
static int tpm_engine_init(ENGINE *);
static int tpm_engine_finish(ENGINE *);
static int tpm_engine_ctrl(ENGINE *, int, long, void *, void (*)());
static EVP_PKEY *tpm_engine_load_key(ENGINE *, const char *, UI_METHOD *, void *);
static int tpm_engine_flush_key_context(TPMI_DH_OBJECT hKey);
#ifndef OPENSSL_NO_RSA
/* rsa functions */
static int tpm_rsa_init(RSA *rsa);
static int tpm_rsa_finish(RSA *rsa);
static int tpm_rsa_priv_dec(int, const unsigned char *, unsigned char *, RSA *, int);
static int tpm_rsa_priv_enc(int, const unsigned char *, unsigned char *, RSA *, int);
#endif
/* The definitions for control commands specific to this engine */
#define TPM_CMD_SO_PATH ENGINE_CMD_BASE
static const ENGINE_CMD_DEFN tpm_cmd_defns[] = {
{TPM_CMD_SO_PATH,
"SO_PATH",
"Specifies the path to the libtpm2.so shared library",
ENGINE_CMD_FLAG_STRING},
{0, NULL, NULL, 0}
};
// for now we will only overwrite the RSA decryption
// operation to go over TPM 2.0.
// Add additional hooks as new use cases pop up
#ifndef OPENSSL_NO_RSA
static RSA_METHOD tpm_rsa = {
"TPM 2.0 RSA method", // name
NULL, // rsa_pub_enc (encrypt)
NULL, // rsa_pub_dec (verify arbitrary data)
tpm_rsa_priv_enc, // rsa_priv_enc (sign)
tpm_rsa_priv_dec, // rsa_priv_dec (decrypt)
NULL, // rsa_mod_exp
BN_mod_exp_mont, // bn_mod_exp
tpm_rsa_init, // init
tpm_rsa_finish, // free
(RSA_FLAG_SIGN_VER | RSA_FLAG_NO_BLINDING | RSA_FLAG_EXT_PKEY),
NULL, // app_data
NULL, /* sign */ // rsa_sign
NULL, /* verify */ // rsa_verify
NULL // rsa_keygen
};
#endif
/* Constants used when creating the ENGINE */
static const char *engine_tpm_id = "tpm2";
static const char *engine_tpm_name = "TPM 2.0 hardware engine support for";
static const char *TPM_LIBNAME = "tpm2";
static TSS_CONTEXT *hContext = NULL_HCONTEXT;
static TPMI_DH_OBJECT hKey = NULL_HKEY;
/* varibles used to get/set CRYPTO_EX_DATA values */
int ex_app_data = TPM_ENGINE_EX_DATA_UNINIT;
/* This is a process-global DSO handle used for loading and unloading
* the TSS library. NB: This is only set (or unset) during an
* init() or finish() call (reference counts permitting) and they're
* operating with global locks, so this should be thread-safe
* implicitly. */
static DSO *tpm_dso = NULL;
/* These are the function pointers that are (un)set when the library has
* successfully (un)loaded. */
static unsigned int (*p_tpm2_File_ReadStructure)();
static unsigned int (*p_tpm2_Context_Create)();
static unsigned int (*p_tpm2_Context_Close)();
static unsigned int (*p_tpm2_TPM_Execute)();
static unsigned int (*p_tpm2_Hash_Generate)();
static unsigned int (*p_tpm2_Structure_Marshal)();
static unsigned int (*p_tpm2_TPM_PrivateKey_Unmarshal)();
static unsigned int (*p_tpm2_TPM_PublicKey_Unmarshal)();
static unsigned int (*p_tpm2_Set_Property)();
/* This internal function is used by ENGINE_tpm() and possibly by the
* "dynamic" ENGINE support too */
static int bind_helper(ENGINE * e)
{
#ifndef OPENSSL_NO_RSA
const RSA_METHOD *meth1;
#endif
if (!ENGINE_set_id(e, engine_tpm_id) ||
!ENGINE_set_name(e, engine_tpm_name) ||
#ifndef OPENSSL_NO_RSA
!ENGINE_set_RSA(e, &tpm_rsa) ||
#endif
!ENGINE_set_destroy_function(e, tpm_engine_destroy) ||
!ENGINE_set_init_function(e, tpm_engine_init) ||
!ENGINE_set_finish_function(e, tpm_engine_finish) ||
!ENGINE_set_ctrl_function(e, tpm_engine_ctrl) ||
!ENGINE_set_load_privkey_function(e, tpm_engine_load_key) ||
!ENGINE_set_cmd_defns(e, tpm_cmd_defns))
return 0;
#ifndef OPENSSL_NO_RSA
/* We know that the "PKCS1_SSLeay()" functions hook properly
* to the tpm-specific mod_exp and mod_exp_crt so we use
* those functions. NB: We don't use ENGINE_openssl() or
* anything "more generic" because something like the RSAref
* code may not hook properly, and if you own one of these
* cards then you have the right to do RSA operations on it
* anyway! */
meth1 = RSA_PKCS1_SSLeay();
if (meth1)
{
tpm_rsa.rsa_mod_exp = meth1->rsa_mod_exp;
tpm_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
tpm_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
}
#endif
/* Ensure the tpm error handling is set up */
ERR_load_TPM_strings();
return 1;
}
static ENGINE *engine_tpm(void)
{
ENGINE *ret = ENGINE_new();
if (!ret)
return NULL;
if (!bind_helper(ret)) {
ENGINE_free(ret);
return NULL;
}
return ret;
}
void ENGINE_load_tpm(void)
{
/* Copied from eng_[openssl|dyn].c */
ENGINE *toadd = engine_tpm();
if (!toadd)
return;
ENGINE_add(toadd);
ENGINE_free(toadd);
ERR_clear_error();
}
/* Destructor (complements the "ENGINE_tpm()" constructor) */
static int tpm_engine_destroy(ENGINE * e)
{
/* Unload the tpm error strings so any error state including our
* functs or reasons won't lead to a segfault (they simply get displayed
* without corresponding string data because none will be found). */
ERR_unload_TPM_strings();
return 1;
}
/* initialisation function */
static int tpm_engine_init(ENGINE * e)
{
void (*p1) ();
void (*p2) ();
void (*p3) ();
void (*p4) ();
void (*p5) ();
void (*p6) ();
void (*p7) ();
void (*p8) ();
void (*p9) ();
TPM_RC result;
if (tpm_dso != NULL) {
TSSerr(TPM_F_TPM_ENGINE_INIT, TPM_R_ALREADY_LOADED);
return 1;
}
if ((tpm_dso = DSO_load(NULL, TPM_LIBNAME, NULL, 0)) == NULL) {
TSSerr(TPM_F_TPM_ENGINE_INIT, TPM_R_DSO_FAILURE);
goto err;
}
if (!(p1 = DSO_bind_func(tpm_dso, TPM_F_File_ReadStructure)) ||
!(p2 = DSO_bind_func(tpm_dso, TPM_F_Context_Create)) ||
!(p3 = DSO_bind_func(tpm_dso, TPM_F_Context_Close)) ||
!(p4 = DSO_bind_func(tpm_dso, TPM_F_TPM_Execute)) ||
!(p5 = DSO_bind_func(tpm_dso, TPM_F_Hash_Generate)) ||
!(p6 = DSO_bind_func(tpm_dso, TPM_F_Structure_Marshal)) ||
!(p7 = DSO_bind_func(tpm_dso, TPM_F_PrivateKey_Unmarshal)) ||
!(p8 = DSO_bind_func(tpm_dso, TPM_F_PublicKey_Unmarshal)) ||
!(p9 = DSO_bind_func(tpm_dso, TPM_F_Set_Property))
) {
TSSerr(TPM_F_TPM_ENGINE_INIT, TPM_R_DSO_FAILURE);
goto err;
}
/* Copy the pointers */
p_tpm2_File_ReadStructure = (unsigned int (*) ()) p1;
p_tpm2_Context_Create = (unsigned int (*) ()) p2;
p_tpm2_Context_Close = (unsigned int (*) ()) p3;
p_tpm2_TPM_Execute = (unsigned int (*) ()) p4;
p_tpm2_Hash_Generate = (unsigned int (*) ()) p5;
p_tpm2_Structure_Marshal = (unsigned int (*) ()) p6;
p_tpm2_TPM_PrivateKey_Unmarshal = (unsigned int (*) ()) p7;
p_tpm2_TPM_PublicKey_Unmarshal = (unsigned int (*) ()) p8;
p_tpm2_Set_Property = (unsigned int (*) ()) p9;
if ((result = p_tpm2_Context_Create(&hContext))) {
TSSerr(TPM_F_TPM_ENGINE_INIT, TPM_R_UNIT_FAILURE);
goto err;
}
/*
* avoid using the tpm0 device TCTI as that will bind
* exclusively to the TPM device. Instead
* use the Kernel TPM Resource Manager as that
* allows concurrent access
*
* N.B: This assumes that the kernel-modules-tpm
* pkg is installed with the modified tpm_crb KLM
*/
if ((result = p_tpm2_Set_Property(hContext,
TPM_DEVICE, "/dev/tpmrm0"))) {
DBG("Failed to set Resource Manager in context (%p): rc %d",
hContext, (int)result);
TSSerr(TPM_F_TPM_ENGINE_INIT, TPM_R_UNIT_FAILURE);
goto err;
}
return 1;
err:
if (hContext != NULL_HCONTEXT) {
p_tpm2_Context_Close(hContext);
hContext = NULL_HCONTEXT;
}
if (tpm_dso) {
DSO_free(tpm_dso);
tpm_dso = NULL;
}
p_tpm2_File_ReadStructure = NULL;
p_tpm2_Context_Create = NULL;
p_tpm2_Context_Close = NULL;
p_tpm2_TPM_Execute = NULL;
p_tpm2_Hash_Generate = NULL;
p_tpm2_Structure_Marshal = NULL;
p_tpm2_TPM_PrivateKey_Unmarshal = NULL;
p_tpm2_TPM_PublicKey_Unmarshal = NULL;
p_tpm2_Set_Property = NULL;
return 0;
}
static int tpm_engine_finish(ENGINE * e)
{
if (tpm_dso == NULL) {
TSSerr(TPM_F_TPM_ENGINE_FINISH, TPM_R_NOT_LOADED);
return 0;
}
if (hKey != NULL_HKEY) {
tpm_engine_flush_key_context(hKey);
hKey = NULL_HKEY;
}
if (hContext != NULL_HCONTEXT) {
p_tpm2_Context_Close(hContext);
hContext = NULL_HCONTEXT;
}
if (!DSO_free(tpm_dso)) {
TSSerr(TPM_F_TPM_ENGINE_FINISH, TPM_R_DSO_FAILURE);
return 0;
}
tpm_dso = NULL;
return 1;
}
int fill_out_rsa_object(RSA *rsa, TPMT_PUBLIC *pub, TPMI_DH_OBJECT hKey)
{
struct rsa_app_data *app_data;
unsigned long exp;
if ((app_data = OPENSSL_malloc(sizeof(struct rsa_app_data))) == NULL) {
TSSerr(TPM_F_TPM_FILL_RSA_OBJECT, ERR_R_MALLOC_FAILURE);
return 0;
}
/* set e in the RSA object */
if (!rsa->e && ((rsa->e = BN_new()) == NULL)) {
TSSerr(TPM_F_TPM_FILL_RSA_OBJECT, ERR_R_MALLOC_FAILURE);
return 0;
}
if (pub->parameters.rsaDetail.exponent == 0)
exp = 65537;
else
exp = pub->parameters.rsaDetail.exponent;
if (!BN_set_word(rsa->e, exp)) {
TSSerr(TPM_F_TPM_FILL_RSA_OBJECT, TPM_R_REQUEST_FAILED);
BN_free(rsa->e);
return 0;
}
/* set n in the RSA object */
if (!rsa->n && ((rsa->n = BN_new()) == NULL)) {
TSSerr(TPM_F_TPM_FILL_RSA_OBJECT, ERR_R_MALLOC_FAILURE);
BN_free(rsa->e);
return 0;
}
if (!BN_bin2bn(pub->unique.rsa.t.buffer, pub->unique.rsa.t.size,
rsa->n)) {
TSSerr(TPM_F_TPM_FILL_RSA_OBJECT, ERR_R_MALLOC_FAILURE);
BN_free(rsa->e);
BN_free(rsa->n);
return 0;
}
#if OPENSSL_VERSION_NUMBER >= 0x10100000
RSA_set0_key(rsa, rsa->n, rsa->e, NULL);
#endif
DBG("Setting hKey(0x%x) in RSA object", hKey);
memset(app_data, 0, sizeof(struct rsa_app_data));
app_data->hKey = hKey;
RSA_set_ex_data(rsa, ex_app_data, app_data);
return 1;
}
static int tpm_engine_flush_key_context(TPMI_DH_OBJECT hKey)
{
TPM_RC rc;
FlushContext_In input;
if (hKey == NULL_HKEY) {
TSSerr(TPM_F_TPM_FLUSH_OBJECT_CONTEXT, TPM_R_INVALID_KEY);
return -1;
}
input.flushHandle = hKey;
if ((rc = p_tpm2_TPM_Execute(hContext,
NULL,
(COMMAND_PARAMETERS *)&input,
NULL,
TPM_CC_FlushContext,
TPM_RH_NULL, NULL, 0))) {
DBG("Context Flush Failed: Ret code %d", rc);
TSSerr(TPM_F_TPM_FLUSH_OBJECT_CONTEXT,
TPM_R_REQUEST_FAILED);
return -1;
}
return 0;
}
static EVP_PKEY *tpm_engine_load_key(ENGINE *e, const char *key_id,
UI_METHOD *ui, void *cb_data)
{
RSA *rsa;
EVP_PKEY *pkey;
BIO *bf;
char oid[128];
TPM_RC rc;
TSSLOADABLE *tssl; // the TPM key
Load_In input;
Load_Out output;
const char *parentPassword = NULL;
TPMI_SH_AUTH_SESSION sessionHandle0 = TPM_RS_PW;
unsigned int sessionAttributes0 = 0;
TPMI_SH_AUTH_SESSION sessionHandle1 = TPM_RH_NULL;
unsigned int sessionAttributes1 = 0;
TPMI_SH_AUTH_SESSION sessionHandle2 = TPM_RH_NULL;
unsigned int sessionAttributes2 = 0;
if (!key_id) {
TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY,
ERR_R_PASSED_NULL_PARAMETER);
return NULL;
}
// check if the file exists
if ((bf = BIO_new_file(key_id, "r")) == NULL) {
TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY,
TPM_R_FILE_NOT_FOUND);
return NULL;
}
tssl = PEM_read_bio_TSSLOADABLE(bf, NULL, NULL, NULL);
BIO_free(bf);
if (!tssl) {
TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY,
TPM_R_FILE_READ_FAILED);
goto load_err;
}
if (OBJ_obj2txt(oid, sizeof(oid), tssl->type, 1) == 0) {
TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, TPM_R_FILE_READ_FAILED);
goto load_err;
}
if (strcmp(OID_loadableKey, oid) == 0) {
DBG ("TSSL key type is of format that can be loaded in TPM 2.0");
} else if (strcmp(OID_12Key, oid) == 0) {
TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY,
TPM_R_TPM_1_2_KEY);
goto load_err;
} else if (strcmp(OID_importableKey, oid) == 0) {
TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY,
TPM_R_KEY_UNSUPPORTED);
goto load_err;
} else {
TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, TPM_R_KEY_UNRECOGNIZED);
goto err;
}
// since this TPM key was wrapped in the Endorsement
// Key hierarchy and its handle was persisted, we will
// specify that as the Parent Handle for the Load operation
if (!tssl->parent) {
TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, TPM_R_KEY_NO_PARENT_HANDLE);
goto load_err;
}
input.parentHandle = ASN1_INTEGER_get(tssl->parent);
DBG ("Got parent handle 0x%x", input.parentHandle);
// unmarshal the public and private key portions from
// within the TPM ASN1 key blob
p_tpm2_TPM_PrivateKey_Unmarshal(&input.inPrivate,
&(tssl->privkey->data),
&(tssl->privkey->length));
p_tpm2_TPM_PublicKey_Unmarshal(&input.inPublic,
&(tssl->pubkey->data),
&(tssl->pubkey->length),
FALSE);
if ((rc = p_tpm2_TPM_Execute(hContext,
(RESPONSE_PARAMETERS *)&output,
(COMMAND_PARAMETERS *)&input,
NULL,
TPM_CC_Load,
sessionHandle0,
parentPassword,
sessionAttributes0,
sessionHandle1,
NULL,
sessionAttributes1,
sessionHandle2,
NULL,
sessionAttributes2,
TPM_RH_NULL, NULL, 0))) {
DBG("Context Load Failed: Ret code %08x", rc);
TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY,
TPM_R_REQUEST_FAILED);
goto load_err;
}
hKey = output.objectHandle;
/* create the new objects to return */
if ((pkey = EVP_PKEY_new()) == NULL) {
goto err;
}
pkey->type = EVP_PKEY_RSA;
if ((rsa = RSA_new()) == NULL) {
EVP_PKEY_free(pkey);
goto err;
}
rsa->meth = &tpm_rsa;
/* call our local init function here */
rsa->meth->init(rsa);
pkey->pkey.rsa = rsa;
if (!fill_out_rsa_object(rsa,
&input.inPublic.publicArea,
hKey)) {
EVP_PKEY_free(pkey);
RSA_free(rsa);
goto err;
}
EVP_PKEY_assign_RSA(pkey, rsa);
return pkey;
err:
tpm_engine_flush_key_context(hKey);
hKey = NULL_HKEY;
TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, ERR_R_MALLOC_FAILURE);
load_err:
//TSSLOADABLE_free(tssl);
return NULL;
}
static int tpm_engine_ctrl(ENGINE * e, int cmd, long i, void *p, void (*f) ())
{
int initialised = ((tpm_dso == NULL) ? 0 : 1);
switch (cmd) {
case TPM_CMD_SO_PATH:
if (p == NULL) {
TSSerr(TPM_F_TPM_ENGINE_CTRL,
ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
if (initialised) {
TSSerr(TPM_F_TPM_ENGINE_CTRL,
TPM_R_ALREADY_LOADED);
return 0;
}
TPM_LIBNAME = (const char *) p;
return 1;
default:
break;
}
TSSerr(TPM_F_TPM_ENGINE_CTRL, TPM_R_CTRL_COMMAND_NOT_IMPLEMENTED);
return 0;
}
static int tpm_rsa_init(RSA *rsa)
{
if (ex_app_data == TPM_ENGINE_EX_DATA_UNINIT)
ex_app_data = RSA_get_ex_new_index(0, NULL, NULL, NULL, NULL);
if (ex_app_data == TPM_ENGINE_EX_DATA_UNINIT) {
TSSerr(TPM_F_TPM_RSA_INIT, TPM_R_REQUEST_FAILED);
return 0;
}
return 1;
}
static int tpm_rsa_finish(RSA *rsa)
{
struct rsa_app_data *app_data = RSA_get_ex_data(rsa, ex_app_data);
OPENSSL_free(app_data);
return 1;
}
static int tpm_rsa_priv_dec(int flen,
const unsigned char *from,
unsigned char *to,
RSA *rsa,
int padding)
{
struct rsa_app_data *app_data = RSA_get_ex_data(rsa, ex_app_data);
TPM_RC result;
UINT32 out_len;
int rv;
RSA_Decrypt_In input;
RSA_Decrypt_Out output;
// the parent object is not passwod protected
// but it may be in the future.
const char *parentPassword = NULL;
TPMI_SH_AUTH_SESSION sessionHandle0 = TPM_RS_PW;
unsigned int sessionAttributes0 = 0;
TPMI_SH_AUTH_SESSION sessionHandle1 = TPM_RH_NULL;
unsigned int sessionAttributes1 = 0;
TPMI_SH_AUTH_SESSION sessionHandle2 = TPM_RH_NULL;
unsigned int sessionAttributes2 = 0;
if (!app_data) {
TSSerr(TPM_F_TPM_RSA_PRIV_DEC, TPM_R_NO_APP_DATA);
if ((rv = RSA_PKCS1_SSLeay()->rsa_priv_dec(flen, from, to, rsa,
padding)) < 0) {
TSSerr(TPM_F_TPM_RSA_PRIV_DEC, TPM_R_REQUEST_FAILED);
}
return rv;
}
// hKey is the handle of the private key that is used for decrypt
if (app_data->hKey == NULL_HKEY) {
TSSerr(TPM_F_TPM_RSA_PRIV_DEC, TPM_R_INVALID_KEY);
return 0;
}
/* handler of the private key that will perform rsa decrypt */
input.keyHandle = app_data->hKey;
// fill in the TPM2RB_PUBLIC_KEY_RSA structure with the
// cipher text and cipher lenght
{
input.label.t.size = 0;
input.cipherText.t.size = flen;
memcpy(input.cipherText.t.buffer, from, flen);
}
/*
* Table 157 - Definition of {RSA} TPMT_RSA_DECRYPT Structure:
* we MAY set the input scheme to TPM_ALG_NULL to allow
* for the encryption algorithm prescribed in the digital
* certificate to be used for encryption
*/
input.inScheme.scheme = TPM_ALG_RSAES; /* TPM_ALG_NULL; */
// decrypt this cipher text using the private key stored inside
// tpm and referenced by hKey
if ((result = p_tpm2_TPM_Execute(hContext,
(RESPONSE_PARAMETERS *)&output,
(COMMAND_PARAMETERS *)&input,
NULL,
TPM_CC_RSA_Decrypt,
sessionHandle0,
parentPassword,
sessionAttributes0,
sessionHandle1,
NULL,
sessionAttributes1,
sessionHandle2,
NULL,
sessionAttributes2,
TPM_RH_NULL, NULL, 0))) {
DBG("RSA Decrypt Failed: Ret code %d", result);
TSSerr(TPM_F_TPM_RSA_PRIV_DEC, TPM_R_REQUEST_FAILED);
return 0;
}
DBG ("Doing RSA Decryption");
// Unmarshal the output data and return decrypted cipher text
// and output length
rv = p_tpm2_Structure_Marshal(&to, &out_len,
&output.message,
(MarshalFunction_t)
TSS_TPM2B_PUBLIC_KEY_RSA_Marshal);
if (rv == 0) {
DBG("writing out %d bytes as a signature", out_len);
return out_len;
}
return 0;
}
static int tpm_rsa_priv_enc(int flen,
const unsigned char *from,
unsigned char *to,
RSA *rsa,
int padding)
{
struct rsa_app_data *app_data = RSA_get_ex_data(rsa, ex_app_data);
TPM_RC result = 0;
UINT32 sig_len;
int rv;
RSA_Decrypt_In input;
RSA_Decrypt_Out output;
// the parent object is not passwod protected
// but it may be in the future.
const char *parentPassword = NULL;
TPMI_SH_AUTH_SESSION sessionHandle0 = TPM_RS_PW;
unsigned int sessionAttributes0 = 0;
TPMI_SH_AUTH_SESSION sessionHandle1 = TPM_RH_NULL;
unsigned int sessionAttributes1 = 0;
TPMI_SH_AUTH_SESSION sessionHandle2 = TPM_RH_NULL;
unsigned int sessionAttributes2 = 0;
if (!app_data) {
TSSerr(TPM_F_TPM_RSA_PRIV_DEC, TPM_R_NO_APP_DATA);
if ((rv = RSA_PKCS1_SSLeay()->rsa_priv_enc(flen, from, to, rsa,
padding)) < 0) {
TSSerr(TPM_F_TPM_RSA_PRIV_ENC, TPM_R_REQUEST_FAILED);
}
return rv;
}
if (padding != RSA_PKCS1_PADDING) {
TSSerr(TPM_F_TPM_RSA_PRIV_ENC, TPM_R_INVALID_PADDING_TYPE);
return 0;
}
// hKey is the handle to the private key that is used for hashing
if (app_data->hKey == NULL_HKEY) {
TSSerr(TPM_F_TPM_RSA_PRIV_ENC, TPM_R_INVALID_KEY);
return 0;
}
/* handler of the private key that will perform signing */
input.keyHandle = app_data->hKey;
/*
* Table 145 - Definition of TPMT_SIG_SCHEME inscheme:
* we will set the input scheme to TPM_ALG_NULL to allow
* for the hash algorithm prescribed in the digital certificate
* to be used for signing.
*
* Note that we are using a Decryption operation instead of ]
* a TPM 2.0 Sign operation because of a serious limitation in the
* IBM TSS that it will only sign digests which it has hashed itself,
* i.e. the hash has a corresponding TPM_ST_HASHCHECK validation
* ticket in TPM memory. Long story short, TPM will only sign
* stuff it knows the OID to.
*
* We will therefore specify a Decyrption operation with our
* own padding applied upto the RSA block size and specify
* a TPM_ALG_NULL hashing scheme so that a decrypt operation
* essentially becomes an encrypt op
*/
input.inScheme.scheme = TPM_ALG_NULL;
/* digest to be signed */
int size = RSA_size(rsa);
input.cipherText.t.size = size;
RSA_padding_add_PKCS1_type_1(input.cipherText.t.buffer,
size, from, flen);
input.label.t.size = 0;
// sign this digest using the private key stored inside
// tpm and referenced by hKey
if ((result = p_tpm2_TPM_Execute(hContext,
(RESPONSE_PARAMETERS *)&output,
(COMMAND_PARAMETERS *)&input,
NULL,
TPM_CC_RSA_Decrypt,
sessionHandle0,
parentPassword,
sessionAttributes0,
sessionHandle1,
NULL,
sessionAttributes1,
sessionHandle2,
NULL,
sessionAttributes2,
TPM_RH_NULL, NULL, 0))) {
DBG("RSA Sign Failed: Ret code %d", result);
TSSerr(TPM_F_TPM_RSA_PRIV_ENC, TPM_R_REQUEST_FAILED);
return 0;
}
// thats right son!!! finally signed
sig_len = output.message.t.size;
memcpy(to, output.message.t.buffer, sig_len);
DBG("writing out %d bytes as a signature", sig_len);
return sig_len;
}
/* This stuff is needed if this ENGINE is being compiled into a self-contained
* shared-library. */
static int bind_fn(ENGINE * e, const char *id)
{
if (id && (strcmp(id, engine_tpm_id) != 0)) {
TSSerr(TPM_F_TPM_BIND_FN, TPM_R_ID_INVALID);
return 0;
}
if (!bind_helper(e)) {
TSSerr(TPM_F_TPM_BIND_FN, TPM_R_REQUEST_FAILED);
return 0;
}
return 1;
}
IMPLEMENT_DYNAMIC_CHECK_FN()
IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)

View File

@ -0,0 +1,147 @@
/*
* Copyright (c) 2017 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
*/
/* ====================================================================
* Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
* This product is inspired by the original TPM 1.2 openssl engine written
* by Kent Yoder <kyoder@users.sf.net> for the Trousers Project. This product
* includes TPM key blob ASN-1 encoding scheme from James Bottomley
* <james.bottomley@HansenPartnership.com>
*
*/
#ifndef _E_TPM_H
#define _E_TPM_H
#include <tss2/tss.h>
#include <tss2/tssutils.h>
#include <tss2/tssresponsecode.h>
#include <tss2/Unmarshal_fp.h>
#include <tss2/tssmarshal.h>
#include <tss2/tsscryptoh.h>
#define TPM_LIB_NAME "tpm2 engine"
#define NULL_HCONTEXT NULL
#define NULL_HKEY 0
void ERR_load_TPM_strings(void);
void ERR_unload_TPM_strings(void);
void ERR_TSS_error(int function, int reason, char *file, int line);
#define TSSerr(f,r) ERR_TSS_error((f),(r),__FILE__,__LINE__)
#define DBG(x, ...) fprintf(stderr, "DEBUG %s:%d %s " x "\n", __FILE__,__LINE__,__FUNCTION__,##__VA_ARGS__)
/* Error codes for the TPM functions. */
/* Function codes. */
#define TPM_F_TPM_ENGINE_CTRL 100
#define TPM_F_TPM_ENGINE_FINISH 101
#define TPM_F_TPM_ENGINE_INIT 102
#define TPM_F_TPM_RSA_PRIV_ENC 103
#define TPM_F_TPM_RSA_PRIV_DEC 104
#define TPM_F_TPM_RSA_FINISH 105
#define TPM_F_TPM_RSA_INIT 106
#define TPM_F_TPM_ENGINE_LOAD_KEY 107
#define TPM_F_TPM_BIND_FN 108
#define TPM_F_TPM_FILL_RSA_OBJECT 109
#define TPM_F_TPM_FLUSH_OBJECT_CONTEXT 110
/* Reason codes. */
#define TPM_R_ALREADY_LOADED 100
#define TPM_R_CTRL_COMMAND_NOT_IMPLEMENTED 101
#define TPM_R_DSO_FAILURE 102
#define TPM_R_MEXP_LENGTH_TO_LARGE 103
#define TPM_R_MISSING_KEY_COMPONENTS 104
#define TPM_R_NOT_INITIALISED 105
#define TPM_R_NOT_LOADED 106
#define TPM_R_OPERANDS_TOO_LARGE 107
#define TPM_R_OUTLEN_TO_LARGE 108
#define TPM_R_REQUEST_FAILED 109
#define TPM_R_UNDERFLOW_CONDITION 110
#define TPM_R_UNDERFLOW_KEYRECORD 111
#define TPM_R_UNIT_FAILURE 112
#define TPM_R_INVALID_KEY_SIZE 113
#define TPM_R_BN_CONVERSION_FAILED 114
#define TPM_R_INVALID_EXPONENT 115
#define TPM_R_REQUEST_TOO_BIG 116
#define TPM_R_NO_APP_DATA 117
#define TPM_R_INVALID_ENC_SCHEME 118
#define TPM_R_INVALID_MSG_SIZE 119
#define TPM_R_INVALID_PADDING_TYPE 120
#define TPM_R_INVALID_KEY 121
#define TPM_R_FILE_NOT_FOUND 122
#define TPM_R_FILE_READ_FAILED 123
#define TPM_R_ID_INVALID 124
#define TPM_R_TPM_1_2_KEY 125
#define TPM_R_KEY_UNSUPPORTED 126
#define TPM_R_KEY_UNRECOGNIZED 127
#define TPM_R_KEY_NO_PARENT_HANDLE 128
/* structure pointed to by the RSA object's app_data pointer.
* this is used to tag TPM meta data in the RSA object and
* use that to distinguish between a vanilla Openssl RSA object
* and a TPM RSA object
*/
struct rsa_app_data
{
TPMI_DH_OBJECT hKey;
// add additional meta data as need be
};
#define TPM_ENGINE_EX_DATA_UNINIT -1
#define RSA_PKCS1_OAEP_PADDING_SIZE (2 * SHA_DIGEST_LENGTH + 2)
#endif

View File

@ -0,0 +1,170 @@
/*
* Copyright (c) 2017 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
*/
/* ====================================================================
* Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
* This product is inspired by the original TPM 1.2 openssl engine written
* by Kent Yoder <kyoder@users.sf.net> for the Trousers Project. This product
* includes TPM key blob ASN-1 encoding scheme from James Bottomley
* <james.bottomley@HansenPartnership.com>
*
*/
#include <stdio.h>
#include <openssl/err.h>
#include <openssl/dso.h>
#include <openssl/engine.h>
#include "e_tpm2.h"
/* BEGIN ERROR CODES */
#ifndef OPENSSL_NO_ERR
static ERR_STRING_DATA TPM_str_functs[] = {
{ERR_PACK(0, TPM_F_TPM_ENGINE_CTRL, 0), "TPM_ENGINE_CTRL"},
{ERR_PACK(0, TPM_F_TPM_ENGINE_FINISH, 0), "TPM_ENGINE_FINISH"},
{ERR_PACK(0, TPM_F_TPM_ENGINE_INIT, 0), "TPM_ENGINE_INIT"},
{ERR_PACK(0, TPM_F_TPM_RSA_PRIV_ENC, 0), "TPM_RSA_PRIV_ENC"},
{ERR_PACK(0, TPM_F_TPM_RSA_PRIV_DEC, 0), "TPM_RSA_PRIV_DEC"},
{ERR_PACK(0, TPM_F_TPM_RSA_FINISH, 0), "TPM_RSA_FINISH"},
{ERR_PACK(0, TPM_F_TPM_RSA_INIT, 0), "TPM_RSA_INIT"},
{ERR_PACK(0, TPM_F_TPM_ENGINE_LOAD_KEY, 0), "TPM_ENGINE_LOAD_KEY"},
{ERR_PACK(0, TPM_F_TPM_BIND_FN, 0), "TPM_BIND_FN"},
{ERR_PACK(0, TPM_F_TPM_FILL_RSA_OBJECT, 0), "TPM_FILL_RSA_OBJECT"},
{ERR_PACK(0, TPM_F_TPM_FLUSH_OBJECT_CONTEXT, 0), "TPM_FLUSH_OBJECT_CONTEXT"},
{0, NULL}
};
static ERR_STRING_DATA TPM_str_reasons[] = {
{TPM_R_ALREADY_LOADED, "already loaded"},
{TPM_R_CTRL_COMMAND_NOT_IMPLEMENTED, "ctrl command not implemented"},
{TPM_R_DSO_FAILURE, "dso failure"},
{TPM_R_MISSING_KEY_COMPONENTS, "missing key components"},
{TPM_R_NOT_INITIALISED, "not initialised"},
{TPM_R_NOT_LOADED, "not loaded"},
{TPM_R_OPERANDS_TOO_LARGE, "operands too large"},
{TPM_R_OUTLEN_TO_LARGE, "outlen to large"},
{TPM_R_REQUEST_FAILED, "request failed"},
{TPM_R_REQUEST_TOO_BIG, "requested number of random bytes > 4096"},
{TPM_R_UNDERFLOW_CONDITION, "underflow condition"},
{TPM_R_UNDERFLOW_KEYRECORD, "underflow keyrecord"},
{TPM_R_UNIT_FAILURE, "unit failure"},
{TPM_R_INVALID_KEY_SIZE, "invalid key size"},
{TPM_R_BN_CONVERSION_FAILED, "bn conversion failed"},
{TPM_R_INVALID_EXPONENT, "invalid exponent"},
{TPM_R_NO_APP_DATA, "no app data in RSA object"},
{TPM_R_INVALID_ENC_SCHEME, "invalid encryption scheme"},
{TPM_R_INVALID_MSG_SIZE, "invalid message size to sign"},
{TPM_R_INVALID_PADDING_TYPE, "invalid padding type"},
{TPM_R_INVALID_KEY, "invalid key"},
{TPM_R_FILE_NOT_FOUND, "file to load not found"},
{TPM_R_FILE_READ_FAILED, "failed reading the key file"},
{TPM_R_ID_INVALID, "engine id doesn't match"},
{TPM_R_TPM_1_2_KEY, "tpm 1.2 key format not supported"},
{TPM_R_KEY_UNSUPPORTED, "unsupported TPM key format"},
{TPM_R_KEY_UNRECOGNIZED, "unrecognized TPM key format"},
{TPM_R_KEY_NO_PARENT_HANDLE, "TPM key has no parent handle"},
{0, NULL}
};
#endif
static ERR_STRING_DATA TPM_lib_name[] = {
{0, TPM_LIB_NAME},
{0, NULL}
};
static int TPM_lib_error_code = 0;
static int TPM_error_init = 1;
void ERR_load_TPM_strings(void)
{
if (TPM_lib_error_code == 0) {
TPM_lib_error_code = ERR_get_next_error_library();
DBG("TPM_lib_error_code is %d", TPM_lib_error_code);
}
if (TPM_error_init) {
TPM_error_init = 0;
#ifndef OPENSSL_NO_ERR
ERR_load_strings(TPM_lib_error_code, TPM_str_functs);
ERR_load_strings(TPM_lib_error_code, TPM_str_reasons);
#endif
TPM_lib_name[0].error = ERR_PACK(TPM_lib_error_code, 0, 0);
ERR_load_strings(0, TPM_lib_name);
}
}
void ERR_unload_TPM_strings(void)
{
if (TPM_error_init == 0) {
#ifndef OPENSSL_NO_ERR
ERR_unload_strings(TPM_lib_error_code, TPM_str_functs);
ERR_unload_strings(TPM_lib_error_code, TPM_str_reasons);
#endif
ERR_load_strings(0, TPM_lib_name);
TPM_error_init = 1;
}
}
void ERR_TSS_error(int function, int reason, char *file, int line)
{
if (TPM_lib_error_code == 0)
TPM_lib_error_code = ERR_get_next_error_library();
ERR_PUT_error(TPM_lib_error_code, function, reason, file, line);
}

View File

@ -0,0 +1,121 @@
/*
* Copyright (c) 2017 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
*/
/* ====================================================================
* Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
* This product is inspired by the original TPM 1.2 openssl engine written
* by Kent Yoder <kyoder@users.sf.net> for the Trousers Project. This product
* includes TPM key blob ASN-1 encoding scheme from James Bottomley
* <james.bottomley@HansenPartnership.com>
*
*/
#ifndef _TPM2_ASN_H
#define _TPM2_ASN_H
#include <openssl/asn1t.h>
#include <openssl/pem.h>
/*
* Define the format of a TPM key file. The current format covers
* both TPM1.2 keys as well as symmetrically encrypted private keys
* produced by TSS2_Import and the TPM2 format public key which
* contains things like the policy but which is cryptographically tied
* to the private key.
*
* TPMKey ::= SEQUENCE {
* type OBJECT IDENTIFIER
* emptyAuth [0] EXPLICIT BOOLEAN OPTIONAL
* parent [1] EXPLICIT INTEGER OPTIONAL
* pubkey [2] EXPLICIT OCTET STRING OPTIONAL
* privkey OCTET STRING
* }
*/
typedef struct {
ASN1_OBJECT *type;
ASN1_BOOLEAN emptyAuth;
ASN1_INTEGER *parent;
ASN1_OCTET_STRING *pubkey;
ASN1_OCTET_STRING *privkey;
} TSSLOADABLE;
/* the two type oids are in the TCG namespace 2.23.133; we choose an
* unoccupied child (10) for keytype file and two values:
* 1 : Key that is directly loadable
* 2 : Key that must first be imported then loaded
*/
#define OID_12Key "2.23.133.10.1"
#define OID_loadableKey "2.23.133.10.2"
#define OID_importableKey "2.23.133.10.3"
ASN1_SEQUENCE(TSSLOADABLE) = {
ASN1_SIMPLE(TSSLOADABLE, type, ASN1_OBJECT),
ASN1_EXP_OPT(TSSLOADABLE, emptyAuth, ASN1_BOOLEAN, 0),
ASN1_EXP_OPT(TSSLOADABLE, parent, ASN1_INTEGER, 1),
ASN1_EXP_OPT(TSSLOADABLE, pubkey, ASN1_OCTET_STRING, 2),
ASN1_SIMPLE(TSSLOADABLE, privkey, ASN1_OCTET_STRING)
} ASN1_SEQUENCE_END(TSSLOADABLE)
IMPLEMENT_ASN1_FUNCTIONS(TSSLOADABLE)
//DECLARE_ASN1_FUNCTIONS(TSSLOADABLE)
/* This is the PEM guard tag */
#define TSSLOADABLE_PEM_STRING "TSS2 KEY BLOB"
static IMPLEMENT_PEM_write_bio(TSSLOADABLE, TSSLOADABLE, TSSLOADABLE_PEM_STRING, TSSLOADABLE)
static IMPLEMENT_PEM_read_bio(TSSLOADABLE, TSSLOADABLE, TSSLOADABLE_PEM_STRING, TSSLOADABLE)
#endif