8.1. Introduction on OpenSSL engine¶
Starting with OpenSSL 0.9.6 an ‘Engine interface’ was added to OpenSSL allowing support for alternative cryptographic implementations. This Engine interface can be used to interface with external crypto devices. The key injection process is secure module specific and is not covered by the Engine interface.
Depending on the capabilities of the attached secure element (e.g. SE050_C, A71CH, …) the following functionality can be made available over the OpenSSL Engine interface:
EC crypto
EC sign/verify
ECDH compute key
Montgomory ECDH
RSA crypto
RSA sign/verify
RSA priv_key_decrypt/pub_key_encrypt
Fetching random data
8.1.1. General¶
8.1.1.1. OpenSSL versions¶
The OpenSSL Engine is compatible with OpenSSL versions 1.0.2 or 1.1.1.
8.1.1.2. OpenSSL Configuration file¶
It’s possible to add OpenSSL engine specific extensions to the OpenSSL configuration file. Using these extensions one can control whether the supported crypto functionality is delegated to the Secure Element or whether it is handled by the OpenSSL SW implementation.
The actual contents of the configuration file depends on the OpenSSL version and the attached
secure element (SE050 or A71CH). The demos/linux/common folder
of this SW package contains
4 reference configuration files covering both SE050 and A71CH for the two supported OpenSSL versions.
The following configuration file fragment (extracted from openssl11_sss_se050.cnf
) highlights
the required changes to enable the full functionality of the SE050_C OpenSSL Engine on an iMX Linux system:
...
# System default
openssl_conf = nxp_engine
...
...
[nxp_engine]
engines = engine_section
[engine_section]
e4sss_se050 = e4sss_se050_section
[e4sss_se050_section]
engine_id = e4sss
dynamic_path = /usr/local/lib/libsss_engine.so
init = 1
default_algorithms = RAND,RSA,EC
One overrules the default OpenSSL configuration file by setting the environment variable
OPENSSL_CONF
to the path of the custom configuration file.
8.1.1.3. Platforms¶
The OpenSSL engine can be used on iMX boards (running Linux) or on Raspberry Pi (running Raspbian).
8.1.2. Keys¶
8.1.2.1. Key Management¶
The cryptographic functionality offered by the OpenSSL engine requires a reference to a key stored inside the Secure Element (exception is RAND_Method). These keys are typically inserted into the Secure Element in a secured environment during production.
OpenSSL requires a key pair, consisting of a private and a public key, to be loaded before the cryptographic operations can be executed. This creates a challenge when OpenSSL is used in combination with a secure element as the private key cannot be extracted out from the Secure Element.
The solution is to populate the OpenSSL Key data structure with only a reference to the Private Key inside the Secure Element instead of the actual Private Key. The public key as read from the Secure Element can still be inserted into the key structure.
OpenSSL crypto API’s are then invoked with these data structure objects as parameters. When the crypto API is routed to the Engine, the OpenSSL engine implementation decodes these key references and invokes the SSS API with correct Key references for a cryptographic operation. If the input key is not reference key, execution will roll back to openssl software implementation
8.1.2.2. EC Reference key format¶
The following provides an example of an EC reference key. The value reserved for the private key has been used to contain:
a pattern of
0x10..00
to fill up the datastructure MSB side to the desired key lengtha 32 bit key identifier (in the example below
0x7DCCBBAA
)a 64 bit magic number (always
0xA5A6B5B6A5A6B5B6
)a byte to describe the key class (
0x10
for Key pair and0x20
for Public key)a byte to describe the key index (use a reserved value
0x00
)
Private-Key: (256 bit)
priv:
10:00:00:00:00:00:00:00:00:00:00:00:00:00:00:
00:00:00:7D:CC:BB:AA:A5:A6:B5:B6:A5:A6:B5:B6:
kk:ii
pub:
04:1C:93:08:8B:26:27:BA:EA:03:D1:BE:DB:1B:DF:
8E:CC:87:EF:95:D2:9D:FC:FC:3A:82:6F:C6:E1:70:
A0:50:D4:B7:1F:F2:A3:EC:F8:92:17:41:60:48:74:
F2:DB:3D:B4:BC:2B:F8:FA:E8:54:72:F6:72:74:8C:
9E:5F:D3:D6:D4
ASN1 OID: prime256v1
Note
The key identifier
0x7DCCBBAA
(stored in big-endian convention) is in front of the magic number0xA5A6B5B6A5A6B5B6
The padding of the private key value and the magic number make it unlikely a normal private key value matches a reference key.
Ensure the value reserved for public key and ASN1 OID contain the values matching the stored key.
Note
For EC montgomery curves, openssl allows only the private key to be set. So the reference key created will not have the valid public key.
8.1.2.3. RSA Reference key format¶
The following provides an example of an RSA reference key.
The value reserved for ‘p’ (aka ‘prime1’) is used as a magic number and is set to ‘1’
The value reserved for ‘q’ (aka ‘prime2’) is used to store the 32 bit key identifier (in the example below 0x6DCCBB11)
The value reserved for ‘(inverse of q) mod p’ (aka ‘IQMP’ or ‘coefficient’) is used to store the magic number 0xA5A6B5B6
Private-Key: (2048 bit)
modulus:
00:b5:48:67:f8:84:ca:51:ac:a0:fb:d8:e0:c9:a7:
72:2a:bc:cb:bc:93:3a:18:6a:0f:a1:ae:d4:73:e6:
...
publicExponent: 65537 (0x10001)
privateExponent:
58:7a:24:39:90:f4:13:ff:bf:2c:00:11:eb:f5:38:
b1:77:dd:3a:54:3c:f0:d5:27:35:0b:ab:8d:94:93:
...
prime1: 1 (0x1)
prime2: 1842133777(0x6DCCBB11)
exponent1:
00:c1:c9:0a:cc:9f:1a:c5:1c:53:e6:c1:3f:ab:09:
db:fb:20:04:38:2a:26:d5:71:33:cd:17:a0:94:bd:
...
exponent2:
24:95:f0:0b:b0:78:a9:d9:f6:5c:4c:e0:67:d8:89:
c1:eb:df:43:54:74:a0:1c:43:e3:6f:d5:97:88:55:
...
coefficient: 2779166134 (0xA5A6B5B6)
Note
Ensure keylength, the value reserved for (private key) modulus and public exponent match the stored key.
The mathematical relation between the different key components is not preserved.
Setting prime1 to ‘1’ makes it impossible that a normal private key matches a reference key.
8.1.3. Building the OpenSSL engine¶
The cmake build system will create an OpenSSL engine for supported platforms.
The resulting OpenSSL engine will be copied to the SW tree in directory
simw-top/sss/plugin/openssl/bin
.
A subsequent make install
will copy the
OpenSSL engine to a standard directory on the file system, in case of iMX Linux e.g.
/usr/local/lib
.
Note
Ensure the following flag is defined when building an application that will be linked against the engine:
-DOPENSSL_LOAD_CONF
8.1.4. Sample scripts to demo OpenSSL Engine¶
The directory simw-top/sss/plugin/openssl/scripts
contains a set of python
scripts. These scripts use the OpenSSL Engine in the context of standard
OpenSSL utilities. They illustrate using the OpenSSL Engine for fetching
random data, EC or RSA crypto operations. The scripts that illustrate EC or
RSA crypto operations depend on prior provisioning of the secure element.
As an example, the following set of commands first creates and provisions EC key material. Then it invokes the OpenSSL Engine for ECDSA sign / verify operations and ECDH calculations. It assumes an SE050 is connected via I2C to an iMX6UL-EVK board:
python3 openssl_provisionEC.py --key_type prime256v1
python3 openssl_EccSign.py --key_type prime256v1
python3 openssl_Ecdh.py --key_type prime256v1
Further details on using these scripts can be found in the following:
8.1.4.1. openssl_rnd.py¶
usage: openssl_rnd.py [-h] [–connection_data CONNECTION_DATA]
Generate few random numbers from the attached secure element.
- optional arguments:
- -h, --help
show this help message and exit
- --connection_data CONNECTION_DATA
Parameter to connect to SE => eg.
COM3
,127.0.0.1:8050
,none
. Default:none
Example invocation:
python openssl_rnd.py --connection_data 127.0.0.1:8050
8.1.4.2. openssl_provisionEC.py¶
- usage: openssl_provisionEC.py [-h] –key_type KEY_TYPE
[–connection_type CONNECTION_TYPE] [–connection_data CONNECTION_DATA] [–subsystem SUBSYSTEM] [–auth_type AUTH_TYPE] [–scpkey SCPKEY]
Provision attached secure element with EC keys
This example generates a complete set of ECC key files (*.pem) (existing ones overwritten). Performs debug reset the attached secure element. Attached secure element provisioned with EC key. Creates reference key from the injected EC key.
- optional arguments:
- -h, --help
show this help message and exit
- required arguments:
- --key_type KEY_TYPE
Supported key types =>
prime192v1
,secp224r1
,prime256v1
,secp384r1
,secp521r1
,brainpoolP160r1
,brainpoolP192r1
,brainpoolP224r1
,brainpoolP256r1
,brainpoolP320r1
,brainpoolP384r1
,brainpoolP512r1
,secp160k1
,secp192k1
,secp224k1
,secp256k1
- optional arguments:
- --connection_type CONNECTION_TYPE
Supported connection types =>
t1oi2c
,sci2c
,vcom
,jrcpv1
,jrcpv2
,pcsc
. Default:t1oi2c
- --connection_data CONNECTION_DATA
Parameter to connect to SE => eg.
COM3
,127.0.0.1:8050
,none
. Default:none
- --subsystem SUBSYSTEM
Supported subsystem =>
se050
,a71ch
,mbedtls
. Default:se050
- --auth_type AUTH_TYPE
Supported subsystem =>
None
,PlatformSCP
,UserID
,ECKey
,AESKey
. Default:None
–scpkey SCPKEY
Example invocation:
python openssl_provisionEC.py --key_type prime256v1
python openssl_provisionEC.py --key_type prime256v1 --connection_data 169.254.0.1:8050
python openssl_provisionEC.py --key_type secp224k1 --connection_type jrcpv2 --connection_data 127.0.0.1:8050
python openssl_provisionEC.py --key_type brainpoolP256r1 --connection_data COM3
python openssl_provisionEC.py --key_type prime256v1 --subsystem a71ch
8.1.4.3. openssl_EccSign.py¶
- usage: openssl_EccSign.py [-h] –key_type KEY_TYPE
[–connection_data CONNECTION_DATA] [–disable_sha1 DISABLE_SHA1]
Validation of Sign Verify with OpenSSL engine using EC Keys
This example showcases sign using reference key, then verify using openssl and vice versa.
- Precondition:
Inject keys using
openssl_provisionEC.py
.
- optional arguments:
- -h, --help
show this help message and exit
- required arguments:
- --key_type KEY_TYPE
Supported key types =>
prime192v1
,secp224r1
,prime256v1
,secp384r1
,secp521r1
,brainpoolP160r1
,brainpoolP192r1
,brainpoolP224r1
,brainpoolP256r1
,brainpoolP320r1
,brainpoolP384r1
,brainpoolP512r1
,secp160k1
,secp192k1
,secp224k1
,secp256k1
- optional arguments:
- --connection_data CONNECTION_DATA
Parameter to connect to SE => eg.
COM3
,127.0.0.1:8050
,none
. Default:none
- --disable_sha1 DISABLE_SHA1
Parameter to disable SHA1 => eg.
True
,False
. Default:False
Example invocation:
python openssl_EccSign.py --key_type prime256v1
python openssl_EccSign.py --key_type secp160k1 --connection_data 127.0.0.1:8050
8.1.4.4. openssl_Ecdh.py¶
- usage: openssl_Ecdh.py [-h] –key_type KEY_TYPE
[–connection_data CONNECTION_DATA] [–disable_sha1 DISABLE_SHA1]
Validation of ECDH with OpenSSL engine using EC keys
This example showcases ECDH between openssl engine and openssl.
- Precondition:
Inject keys using
openssl_provisionEC.py
.
- optional arguments:
- -h, --help
show this help message and exit
- required arguments:
- --key_type KEY_TYPE
Supported key types =>
prime192v1
,secp224r1
,prime256v1
,secp384r1
,secp521r1
,brainpoolP160r1
,brainpoolP192r1
,brainpoolP224r1
,brainpoolP256r1
,brainpoolP320r1
,brainpoolP384r1
,brainpoolP512r1
,secp160k1
,secp192k1
,secp224k1
,secp256k1
- optional arguments:
- --connection_data CONNECTION_DATA
Parameter to connect to SE => eg.
COM3
,127.0.0.1:8050
,none
. Default:none
- --disable_sha1 DISABLE_SHA1
Parameter to disable SHA1 => eg.
True
,False
. Default:False
Example invocation:
python openssl_Ecdh.py --key_type prime256v1
python openssl_Ecdh.py --key_type secp160k1 --connection_data 127.0.0.1:8050
8.1.4.5. ecc_all.py¶
- usage: ecc_all.py [-h] [–connection_type CONNECTION_TYPE]
[–connection_data CONNECTION_DATA] [–subsystem SUBSYSTEM] [–auth_type AUTH_TYPE] [–scpkey SCPKEY] [–disable_sha1 DISABLE_SHA1] [–fips FIPS]
Validation of OpenSSL Engine using EC keys
This example injects keys with different supported EC Curves, then showcases ECDH & ECDSA using those keys.
- optional arguments:
- -h, --help
show this help message and exit
- --connection_type CONNECTION_TYPE
Supported connection types =>
t1oi2c
,sci2c
,vcom
,jrcpv1
,jrcpv2
,pcsc
. Default:t1oi2c
- --connection_data CONNECTION_DATA
Parameter to connect to SE => eg.
COM3
,127.0.0.1:8050
,none
. Default:none
- --subsystem SUBSYSTEM
Supported subsystem =>
se051
,se050
,a71ch
. Default:se050
- --auth_type AUTH_TYPE
Supported subsystem =>
None
,PlatformSCP
,UserID
,ECKey
,AESKey
. Default:None
–scpkey SCPKEY –disable_sha1 DISABLE_SHA1
Parameter to disable SHA1 => eg.
True
,False
. Default:False
- --fips FIPS
FIPS Testing => eg.
True
,False
. Default:False
Example invocation:
python ecc_all.py
python ecc_all.py --connection_data 169.254.0.1:8050
python ecc_all.py --connection_data 127.0.0.1:8050 --connection_type jrcpv2
python ecc_all.py --connection_data COM3
8.1.4.6. openssl_provisionRSA.py¶
- usage: openssl_provisionRSA.py [-h] –key_type KEY_TYPE
[–connection_type CONNECTION_TYPE] [–connection_data CONNECTION_DATA] [–subsystem SUBSYSTEM] [–auth_type AUTH_TYPE] [–scpkey SCPKEY]
Provision attached secure element with RSA keys
This example generates a complete set of RSA key files (*.pem) (existing ones overwritten). Performs debug reset the attached secure element. Attached secure element provisioned with RSA key. Creates reference key from the injected RSA key.
- optional arguments:
- -h, --help
show this help message and exit
- required arguments:
- --key_type KEY_TYPE
Supported key types =>
rsa1024
,rsa2048
,rsa3072
,rsa4096
- optional arguments:
- --connection_type CONNECTION_TYPE
Supported connection types =>
t1oi2c
,sci2c
,vcom
,jrcpv1
,jrcpv2
,pcsc
. Default:t1oi2c
- --connection_data CONNECTION_DATA
Parameter to connect to SE => eg.
COM3
,127.0.0.1:8050
,none
. Default:none
- --subsystem SUBSYSTEM
Supported subsystem =>
se050
,mbedtls
. Default:se050
- --auth_type AUTH_TYPE
Supported subsystem =>
None
,PlatformSCP
,UserID
,ECKey
,AESKey
. Default:None
–scpkey SCPKEY
Example invocation:
python openssl_provisionRSA.py --key_type rsa1024
python openssl_provisionRSA.py --key_type rsa2048 --connection_data 169.254.0.1:8050
python openssl_provisionRSA.py --key_type rsa2048 --connection_data 127.0.0.1:8050 --connection_type jrcpv2
python openssl_provisionRSA.py --key_type rsa2048 --connection_data COM3
8.1.4.7. openssl_RSA.py¶
- usage: openssl_RSA.py [-h] –key_type KEY_TYPE
[–connection_data CONNECTION_DATA] [–disable_sha1 DISABLE_SHA1]
Validation of OpenSSL Engine using RSA keys
This example showcases crypto operations and sign verify operations using RSA keys.
- optional arguments:
- -h, --help
show this help message and exit
- required arguments:
- --key_type KEY_TYPE
Supported key types =>
rsa1024
,rsa2048
,rsa3072
,rsa4096
- optional arguments:
- --connection_data CONNECTION_DATA
Parameter to connect to SE => eg.
COM3
,127.0.0.1:8050
,none
. Default:none
- --disable_sha1 DISABLE_SHA1
Parameter to disable SHA1 => eg.
True
,False
. Default:False
Example invocation:
python openssl_RSA.py --key_type rsa2048
python openssl_RSA.py --key_type rsa4096 --connection_data 127.0.0.1:8050
8.1.4.8. rsa_all.py¶
- usage: rsa_all.py [-h] [–connection_data CONNECTION_DATA]
[–connection_type CONNECTION_TYPE] [–subsystem SUBSYSTEM] [–auth_type AUTH_TYPE] [–scpkey SCPKEY] [–disable_sha1 DISABLE_SHA1] [–fips FIPS]
Validation of OpenSSL Engine using RSA keys
This example injects keys with different supported RSA keys, then showcases Crypto & sign verify operations using those keys.
- optional arguments:
- -h, --help
show this help message and exit
- --connection_data CONNECTION_DATA
Parameter to connect to SE => eg.
COM3
,127.0.0.1:8050
,none
. Default:none
- --connection_type CONNECTION_TYPE
Supported connection types =>
t1oi2c
,sci2c
,vcom
,jrcpv1
,jrcpv2
,pcsc
. Default:t1oi2c
- --subsystem SUBSYSTEM
Supported subsystem =>
se050
. Default:se050
- --auth_type AUTH_TYPE
Supported subsystem =>
None
,PlatformSCP
,UserID
,ECKey
,AESKey
. Default:None
–scpkey SCPKEY –disable_sha1 DISABLE_SHA1
Parameter to disable SHA1 => eg.
True
,False
. Default:False
- --fips FIPS
FIPS Testing => eg.
True
,False
. Default:False
Example invocation:
python rsa_all.py
python rsa_all.py --connection_data 169.254.0.1:8050
python rsa_all.py --connection_data 127.0.0.1:8050 --connection_type jrcpv2
python rsa_all.py --connection_data COM3
8.1.4.9. openssl_provisionEC_mont.py¶
- usage: openssl_provisionEC_mont.py [-h] –key_type KEY_TYPE
[–connection_type CONNECTION_TYPE] [–connection_data CONNECTION_DATA] [–subsystem SUBSYSTEM] [–auth_type AUTH_TYPE] [–scpkey SCPKEY]
Provision attached secure element with EC montogomery keys
This example generates EC montogomery key files (*.pem) (existing ones overwritten). Performs debug reset the attached secure element. Attached secure element provisioned with EC montogomery key. Creates reference key from the injected EC montogomery key.
- optional arguments:
- -h, --help
show this help message and exit
- required arguments:
- --key_type KEY_TYPE
Supported key types =>
x25519
,x448
- optional arguments:
- --connection_type CONNECTION_TYPE
Supported connection types =>
t1oi2c
,sci2c
,vcom
,jrcpv1
,jrcpv2
,pcsc
. Default:t1oi2c
- --connection_data CONNECTION_DATA
Parameter to connect to SE => eg.
COM3
,127.0.0.1:8050
,none
. Default:none
- --subsystem SUBSYSTEM
Supported subsystem =>
se050
,a71ch
,mbedtls
. Default:se050
- --auth_type AUTH_TYPE
Supported subsystem =>
None
,PlatformSCP
,UserID
,ECKey
,AESKey
. Default:None
–scpkey SCPKEY
Example invocation:
python openssl_provisionEC_mont.py --key_type x25519
python openssl_provisionEC_mont.py --key_type x25519 --connection_data 169.254.0.1:8050
python openssl_provisionEC_mont.py --key_type x448 --connection_type jrcpv2 --connection_data 127.0.0.1:8050
python openssl_provisionEC_mont.py --key_type x448 --connection_data COM3
8.1.4.10. openssl_Ecdh_mont.py¶
- usage: openssl_Ecdh_mont.py [-h] –key_type KEY_TYPE
[–connection_type CONNECTION_TYPE] [–connection_data CONNECTION_DATA]
Validation of Montgomery ECDH with OpenSSL engine using EC mont keys
This example showcases montogomery ECDH between openssl engine and openssl.
- Precondition:
Inject keys using
openssl_provisionEC_mont.py
.
- optional arguments:
- -h, --help
show this help message and exit
- required arguments:
- --key_type KEY_TYPE
Supported key types =>
x25519
,x448
- optional arguments:
- --connection_type CONNECTION_TYPE
Supported connection types =>
t1oi2c
,sci2c
,vcom
,jrcpv1
,jrcpv2
,pcsc
. Default:t1oi2c
- --connection_data CONNECTION_DATA
Parameter to connect to SE => eg.
COM3
,127.0.0.1:8050
,none
. Default:none
Example invocation:
python openssl_Ecdh_mont.py --key_type x448
python openssl_Ecdh_mont.py --key_type x25519 --connection_type jrcpv2 --connection_data 127.0.0.1:8050