Expert OP-TEE and PKCS#11 Support for Secure and Reliable Embedded Systems
Are you looking for a reliable and secure solution for your embedded platform like STM32MP1 or i.MX? Look no further! Our team of experts specializes in setting up and customizing secure bootchains with TF-A, OP-TEE, U-Boot, Linux, and more. We understand the importance of ensuring that only authorized software runs on your device and that secure connections are established to your cloud backend through OP-TEE. We have extensive experience working with all different kinds of embedded systems and have successfully set up security-enhanced trusted systems with Secure-Boot and network TEE-Apps.
Our services are tailored to meet the specific needs of our clients. We understand the significance of maintaining the authenticity of your embedded systems to ensure that connected entities can confidently communicate with only authorized devices, preventing cloning and unauthorized data transmission.
It is the importance of keeping private keys for SSL connections secure within OP-TEE.
Contact us today to learn more about our OP-TEE and PKCS#11 support services.
Exemplary use of OP-TEE (including PKCS#11) on a STM32MP1
To further illustrate the capabilities of OP-TEE (including PKCS#11) on a STM32MP1, we have provided the following examples and explanations of their implementation.
OP-TEE Function testing
To ensure that OP-TEE functions as intended, xtest is a useful tool for verification.
$ xtest -t pkcs11 Result of testsuite pkcs11: 3535 subtests of which 0 failed 25 test cases of which 0 failed 0 test cases were skipped TEE test application done!
Supported OP-TEE mechanisms
$ alias p11='pkcs11-tool --module /usr/lib/libckteec.so.0' $ p11 -M Using slot 0 with a present token (0x0) Supported mechanisms: SHA224-RSA-PKCS-PSS, keySize={256,4096}, sign, verify SHA224-RSA-PKCS, keySize={256,4096}, sign, verify SHA512-RSA-PKCS-PSS, keySize={256,4096}, sign, verify SHA384-RSA-PKCS-PSS, keySize={256,4096}, sign, verify SHA256-RSA-PKCS-PSS, keySize={256,4096}, sign, verify SHA512-RSA-PKCS, keySize={256,4096}, sign, verify SHA384-RSA-PKCS, keySize={256,4096}, sign, verify SHA256-RSA-PKCS, keySize={256,4096}, sign, verify SHA1-RSA-PKCS-PSS, keySize={256,4096}, sign, verify RSA-PKCS-OAEP, keySize={256,4096}, encrypt, decrypt SHA1-RSA-PKCS, keySize={256,4096}, sign, verify MD5-RSA-PKCS, keySize={256,4096}, sign, verify RSA-PKCS-PSS, sign, verify RSA-PKCS, keySize={256,4096}, encrypt, decrypt, sign, verify RSA-PKCS-KEY-PAIR-GEN, keySize={256,4096}, generate_key_pair ECDSA-SHA512, keySize={160,521}, sign, verify ECDSA-SHA384, keySize={160,521}, sign, verify ECDSA-SHA256, keySize={160,521}, sign, verify ECDSA-SHA224, keySize={160,521}, sign, verify ECDSA-SHA1, keySize={160,521}, sign, verify ECDSA, keySize={160,521}, sign, verify ECDSA-KEY-PAIR-GEN, keySize={160,521}, generate_key_pair mechtype-0x272, keySize={32,128}, sign, verify mechtype-0x262, keySize={32,128}, sign, verify mechtype-0x252, keySize={24,128}, sign, verify mechtype-0x257, keySize={14,64}, sign, verify SHA-1-HMAC-GENERAL, keySize={10,64}, sign, verify MD5-HMAC-GENERAL, keySize={8,64}, sign, verify SHA512-HMAC, keySize={32,128}, sign, verify SHA384-HMAC, keySize={32,128}, sign, verify SHA256-HMAC, keySize={24,128}, sign, verify SHA224-HMAC, keySize={14,64}, sign, verify SHA-1-HMAC, keySize={10,64}, sign, verify MD5-HMAC, keySize={8,64}, sign, verify SHA512, digest SHA384, digest SHA256, digest SHA224, digest SHA-1, digest MD5, digest GENERIC-SECRET-KEY-GEN, keySize={1,4096}, generate AES-KEY-GEN, keySize={16,32}, generate AES-CBC-ENCRYPT-DATA, derive AES-ECB-ENCRYPT-DATA, derive mechtype-0x108B, keySize={16,32}, sign, verify AES-CMAC, keySize={16,32}, sign, verify mechtype-0x1089, keySize={16,32}, encrypt, decrypt AES-CTR, keySize={16,32}, encrypt, decrypt AES-CBC-PAD, keySize={16,32}, encrypt, decrypt AES-CBC, keySize={16,32}, encrypt, decrypt, wrap, unwrap AES-ECB, keySize={16,32}, encrypt, decrypt, wrap, unwrap
List available PKCS11 slots
$ p11 -L Available slots: Slot 0 (0x0): OP-TEE PKCS11 TA - TEE UUID 12dc11df-2674-561e-8f49-8afb3a4121df token state: uninitialized Slot 1 (0x1): OP-TEE PKCS11 TA - TEE UUID 12dc11df-2674-561e-8f49-8afb3a4121df token state: uninitialized Slot 2 (0x2): OP-TEE PKCS11 TA - TEE UUID 12dc11df-2674-561e-8f49-8afb3a4121df token state: uninitializedInitialize a token
$ p11 --init-token --label test-token --so-pin 1234 Using slot 0 with a present token (0x0) I/TA: PKCS11 token 0: initialized Token successfully initialized $ p11 -L Available slots: Slot 0 (0x0): OP-TEE PKCS11 TA - TEE UUID 12dc11df-2674-561e-8f49-8afb3a4121df token label : test-token token manufacturer : Linaro token model : OP-TEE TA token flags : login required, rng, token initialized hardware version : 0.0 firmware version : 0.1 serial num : 0000000000000000 pin min/max : 4/128 Slot 1 (0x1): OP-TEE PKCS11 TA - TEE UUID 12dc11df-2674-561e-8f49-8afb3a4121df token state: uninitialized Slot 2 (0x2): OP-TEE PKCS11 TA - TEE UUID 12dc11df-2674-561e-8f49-8afb3a4121df token state: uninitialize
Create a keypair for SSH on OP-TEE its PKCS#11
$ p11 --label test-token --login --so-pin 1234 --init-pin --pin ABCD Using slot 0 with a present token (0x0) I/TA: PKCS11 session 1: login I/TA: PKCS11 session 1: init PIN User PIN successfully initialized $ p11 --label test-token --pin ABCD --keypairgen --key-type EC:prime256v1 --id 2 --label ssh-key Using slot 0 with a present token (0x0) I/TA: PKCS11 session 1: login Key pair generated: Private Key Object; EC label: ssh-key ID: 02 Usage: sign, derive Access: sensitive, always sensitive, never extractable, local Public Key Object; EC EC_POINT 256 bits EC_POINT: 044104302867f8c7ecdc99abb62746[snip] EC_PARAMS: 06082a8648ce3d030107 label: ssh-key ID: 02 Usage: verify, derive Access: local Export public key stored in OP-TEE HSM for OpenSSH: $ ssh-keygen -D libckteec.so.0 -e ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHA[snip]
One can put this public-key on a ssh-server (.ssh/authorized_keys) and start a login (private key never leaves OP-TEE 'never extractable'):
$ ssh -I libckteec.so.0 username@172.16.21.1 Enter PIN for 'test-token': I/TA: PKCS11 session 1: login Last login: Tue Jul 12 11:26:39 2022 from 192.168.0.22 username@linuxbox:~$
Create different keys
$ p11 --token-label test-token --pin ABCD --keypairgen --key-type RSA:2048 --id 0123 --label rsa-test-key I/TA: PKCS11 session 1: login Key pair generated: Private Key Object; RSA label: rsa-test-key ID: 0123 Usage: decrypt, sign Access: sensitive, always sensitive, never extractable, local Public Key Object; RSA 2048 bits label: rsa-test-key ID: 0123 Usage: encrypt, verify Access: local $ p11 --token-label test-token --pin ABCD --keypairgen --key-type EC:secp384r1 --id 3 --label ecc-key1 I/TA: PKCS11 session 1: login Key pair generated: Private Key Object; EC label: ecc-key1 ID: 03 Usage: sign, derive Access: sensitive, always sensitive, never extractable, local Public Key Object; EC EC_POINT 384 bits EC_POINT: 0461043661b1e98e2e525144bda215d[snip] EC_PARAMS: 06052b81040022 label: ecc-key1 ID: 03 Usage: verify, derive Access: local $ p11 --token-label test-token --keygen --key-type AES:32 --label aes-test-key --id 5 Key generated: Secret Key Object; AES length 32 warning: PKCS11 function C_GetAttributeValue(VALUE) failed: rv = CKR_ATTRIBUTE_SENSITIVE (0x11) label: aes-test-key ID: 05 Usage: encrypt, decrypt, wrap, unwrap Access: never extractable, local
Show all the different keys
$ p11 --list-objects Using slot 0 with a present token (0x0) Secret Key Object; AES length 32 warning: PKCS11 function C_GetAttributeValue(VALUE) failed: rv = CKR_ATTRIBUTE_SENSITIVE (0x11) label: aes-test-key ID: 05 Usage: encrypt, decrypt, wrap, unwrap Access: never extractable, local Public Key Object; EC EC_POINT 384 bits EC_POINT: 0461043661b1e98e2e525144bda215d9bca6[snip] EC_PARAMS: 06052b81040022 label: ecc-key1 ID: 03 Usage: verify, derive Access: local Public Key Object; RSA 2048 bits label: rsa-test-key ID: 0123 Usage: encrypt, verify Access: local Public Key Object; EC EC_POINT 256 bits EC_POINT: 0441040ff7ccda64398c865af82c0ff76b8622763f4b[snip] EC_PARAMS: 06082a8648ce3d030107 label: ssh-key ID: 02 Usage: verify, derive Access: local
OpenSSL usage example (sign and verify)
$ dd if=/dev/random bs=512 count=2 of=in.dat 2+0 records in 2+0 records out 1024 bytes (1.0 kB, 1.0 KiB) copied, 0.00639621 s, 160 kB/s $ p11 --sign -m SHA384-RSA-PKCS-PSS --id 0123 -i in.dat -o out.dat.sig-pss --pin ABCD Using slot 0 with a present token (0x0) I/TA: PKCS11 session 1: login Using signature algorithm SHA384-RSA-PKCS-PSS PSS parameters: hashAlg=SHA384, mgf=MGF1-SHA384, salt_len=48 B $ openssl dgst -engine pkcs11 -keyform engine -verify "pkcs11:token=test-token;id=%01%23;type=public" \ -signature out.dat.sig-pss -sigopt rsa_padding_mode:pss -sha384 in.dat Engine "pkcs11" set. Verified OK
OpenSSL create certificate request
$ openssl req -new -subj '/CN=test/' -sha256 -engine pkcs11 -keyform engine -key "pkcs11:token=test-token;id=%03" Engine "pkcs11" set. Enter PKCS#11 token PIN for test-token: I/TA: PKCS11 session 1: login -----BEGIN CERTIFICATE REQUEST----- MIIBBjCBjgIBADAPMQ0wCwYDVQQDDAR0ZXN0MHYwEAYHKoZIzj0CAQYFK4EEACID YgAENmGx6Y4uUlFEvaIV2bymDoCMBBftWGyehbeIoo/uhJf+OHUXuCbnlCBsLz+D 40wxGIVe7CmdmfKF53otwdPpMT9xac0FV/7W+NZeuBfJg07opnwd/zAq3OFFCVUG I3lXoAAwCgYIKoZIzj0EAwIDZwAwZAIwGtRMvWctVsafGy7ncs2csjz/fETHmKZj 2U3GIh0bIcVjtnwzKyYwGaoD0OcuD2IXAjBcV1awCTe0dqLTexJHbONKLriRAkvB XksvAVEeF1Pb5DAgm/MMxsd12YwsNKS83To= -----END CERTIFICATE REQUEST-----
OpenSSL generic SSL/TLS server example with PKCS#11 on OP-TEE
$ openssl req -x509 -newkey rsa:1024 -keyout key.pem -out cert.pem -days 365 ...................................++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .....++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Enter PEM pass phrase: Verifying - Enter PEM pass phrase: ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:DE State or Province Name (full name) [Some-State]: Locality Name (eg, city) []: Organization Name (eg, company) [Internet Widgits Pty Ltd]: Organizational Unit Name (eg, section) []: Common Name (e.g. server FQDN or YOUR name) []:Test Certificate Email Address []: $ p11 --token-label test-token --pin ABCD -w key.pem -y privkey --id 9 --label importkey I/TA: PKCS11 session 1: login Enter PEM pass phrase: Created private key: Private Key Object; RSA label: importkey ID: 09 Usage: none Access: sensitive $ openssl s_server -engine pkcs11 -keyform engine -key "pkcs11:token=test-token;id=%09" -cert cert.pem Engine "pkcs11" set. Enter PKCS#11 token PIN for test-token: I/TA: PKCS11 session 1: login Using default temp DH parameters ACCEPT
OpenSSL certificate creation
$ p11 --token-label test-token --pin ABCD --keypairgen --key-type EC:prime256v1 --id 7 --label ecc-key2 I/TA: PKCS11 session 1: login Key pair generated: Private Key Object; EC label: ecc-key2 ID: 07 Usage: sign, derive Access: sensitive, always sensitive, never extractable, local Public Key Object; EC EC_POINT 256 bits EC_POINT: 04410436d9d802f525f8edeba3609c4eaeb4282b812c1191dc553[snip] EC_PARAMS: 06082a8648ce3d030107 label: ecc-key2 ID: 07 Usage: verify, derive Access: local $ openssl req -subj /CN=ectest -new -x509 -key "pkcs11:token=test-token;id=%07;type=public;pin-value=ABCD" \ -engine pkcs11 -keyform engine -out /tmp/cert.pem Engine "pkcs11" set. I/TC: got HUK I/TC: got HUK I/TC: got HUK Enter PKCS#11 token PIN for test-token: I/TA: PKCS11 session 1: login $ openssl x509 -in /tmp/cert.pem -text Certificate: Data: Version: 3 (0x2) Serial Number: 0b:82:84:b6:5c:2d:5e:34:e1:6d:41:ab:97:98:20:d0:b7:1f:24:6c Signature Algorithm: ecdsa-with-SHA256 Issuer: CN = ectest Validity Not Before: Mar 11 14:14:23 2022 GMT Not After : Apr 10 14:14:23 2022 GMT Subject: CN = ectest Subject Public Key Info: Public Key Algorithm: id-ecPublicKey Public-Key: (256 bit) pub: 04:36:d9:d8:02:f5:25:f8:ed:eb:a3:60:9c:4e:ae: b4:28:2b:81:2c:11:91:dc:55:3a:78:18:02:c8:5e: cc:bb:03:88:14:6e:88:a3:92:de:5d:f8:1c:93:1c: 1f:02:f0:cb:0c:37:53:61:bd:17:fc:c8:86:4b:a4: 33:e6:32:e7:36 ASN1 OID: prime256v1 NIST CURVE: P-256 X509v3 extensions: X509v3 Subject Key Identifier: 23:83:E4:10:7E:4D:0D:F4:C8:74:31:BE:F5:FD:C9:78:E2:55:13:5D X509v3 Authority Key Identifier: 23:83:E4:10:7E:4D:0D:F4:C8:74:31:BE:F5:FD:C9:78:E2:55:13:5D X509v3 Basic Constraints: critical CA:TRUE Signature Algorithm: ecdsa-with-SHA256 Signature Value: 30:45:02:20:0e:1d:35:40:de:7a:09:45:a9:04:7f:b7:a9:1e: 2a:15:ef:4a:16:ca:34:17:b8:9f:57:a6:bb:5f:84:83:d2:50: 02:21:00:93:7a:f3:7b:1d:6d:5d:d8:88:4d:0b:47:00:4f:ec: 65:f3:03:4b:87:63:90:1b:00:dd:e9:6d:30:24:f5:3e:68 -----BEGIN CERTIFICATE----- MIIBdzCCAR2gAwIBAgIUC4KEtlwtXjThbUGrl5gg0LcfJGwwCgYIKoZIzj0EAwIw ETEPMA0GA1UEAwwGZWN0ZXN0MB4XDTIyMDMxMTE0MTQyM1oXDTIyMDQxMDE0MTQy M1owETEPMA0GA1UEAwwGZWN0ZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE NtnYAvUl+O3ro2CcTq60KCuBLBGR3FU6eBgCyF7MuwOIFG6Io5LeXfgckxwfAvDL DDdTYb0X/MiGS6Qz5jLnNqNTMFEwHQYDVR0OBBYEFCOD5BB+TQ30yHQxvvX9yXji VRNdMB8GA1UdIwQYMBaAFCOD5BB+TQ30yHQxvvX9yXjiVRNdMA8GA1UdEwEB/wQF MAMBAf8wCgYIKoZIzj0EAwIDSAAwRQIgDh01QN56CUWpBH+3qR4qFe9KFso0F7if V6a7X4SD0lACIQCTevN7HW1d2IhNC0cAT+xl8wNLh2OQGwDd6W0wJPU+aA== -----END CERTIFICATE-----
OpenSSL cURL usage example
$ openssl req -subj /CN=mytest -new -x509 -nodes -newkey ec:<(openssl ecparam -name prime256v1) \ -keyout /tmp/key2.key -out /tmp/cert2.key -days 365 $ p11 --token-label test-token --pin ABCD -w /tmp/key2.key -y privkey --id 4 --label my_importkey \ --key-type EC:prime256v1 --usage-sign --usage-derive $ p11 --token-label test-token --pin ABCD -w /tmp/cert2.key -y cert --id 4 --label my_importkey \ --key-type EC:prime256v1 --usage-sign --usage-derive $ curl -E "pkcs11:token=test-token;id=%04;type=public;pin-value=ABCD" \ --key "pkcs11:token=test-token;id=%04;pin-value=ABCD"