loadexternal.sh 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. # SPDX-License-Identifier: BSD-3-Clause
  2. source helpers.sh
  3. alg_primary_obj=sha256
  4. alg_primary_key=rsa
  5. alg_create_obj=sha256
  6. alg_create_key=hmac
  7. file_primary_key_ctx=context.p_"$alg_primary_obj"_"$alg_primary_key"
  8. file_loadexternal_key_pub=opu_"$alg_create_obj"_"$alg_create_key"
  9. file_loadexternal_key_priv=opr_"$alg_create_obj"_"$alg_create_key"
  10. file_loadexternal_key_name=name.loadexternal_"$alg_primary_obj"_\
  11. "$alg_primary_key"-"$alg_create_obj"_"$alg_create_key"
  12. file_loadexternal_key_ctx=ctx_loadexternal_out_"$alg_primary_obj"_\
  13. "$alg_primary_key"-"$alg_create_obj"_"$alg_create_key"
  14. file_loadexternal_output=loadexternal_"$file_loadexternal_key_ctx"
  15. Handle_parent=0x81010019
  16. cleanup() {
  17. rm -f $file_primary_key_ctx $file_loadexternal_key_pub \
  18. $file_loadexternal_key_priv $file_loadexternal_key_name \
  19. $file_loadexternal_key_ctx $file_loadexternal_output private.pem public.pem \
  20. plain.txt plain.rsa.dec key.ctx public.ecc.pem private.ecc.pem \
  21. data.in.digest data.out.signed ticket.out name.bin stdout.yaml passfile \
  22. private.pem
  23. if [ $(ina "$@" "keep_handle") -ne 0 ]; then
  24. tpm2 evictcontrol -Q -Co -c $Handle_parent 2>/dev/null || true
  25. fi
  26. if [ $(ina "$@" "no-shut-down") -ne 0 ]; then
  27. shut_down
  28. fi
  29. }
  30. trap cleanup EXIT
  31. start_up
  32. cleanup "no-shut-down"
  33. tpm2 clear
  34. run_tss_test() {
  35. tpm2 createprimary -Q -C e -g $alg_primary_obj -G $alg_primary_key \
  36. -c $file_primary_key_ctx
  37. tpm2 create -Q -g $alg_create_obj -G $alg_create_key \
  38. -u $file_loadexternal_key_pub -r $file_loadexternal_key_priv \
  39. -C $file_primary_key_ctx
  40. tpm2 loadexternal -Q -C n -u $file_loadexternal_key_pub \
  41. -c $file_loadexternal_key_ctx
  42. tpm2 evictcontrol -Q -C o -c $file_primary_key_ctx $Handle_parent
  43. # Test with Handle
  44. cleanup "keep_handle" "no-shut-down"
  45. tpm2 create -Q -C $Handle_parent -g $alg_create_obj -G $alg_create_key \
  46. -u $file_loadexternal_key_pub -r $file_loadexternal_key_priv
  47. tpm2 loadexternal -Q -C n -u $file_loadexternal_key_pub \
  48. -c $file_loadexternal_key_ctx
  49. # Test with default hierarchy (and handle)
  50. cleanup "keep_handle" "no-shut-down"
  51. tpm2 create -Q -C $Handle_parent -g $alg_create_obj -G $alg_create_key \
  52. -u $file_loadexternal_key_pub -r $file_loadexternal_key_priv
  53. tpm2 loadexternal -Q -u $file_loadexternal_key_pub \
  54. -c $file_loadexternal_key_ctx
  55. cleanup "no-shut-down"
  56. }
  57. # Test loading an OSSL generated private key with a password
  58. run_rsa_test() {
  59. openssl genrsa -out private.pem $1
  60. openssl rsa -in private.pem -out public.pem -outform PEM -pubout
  61. echo "hello world" > plain.txt
  62. openssl rsautl -encrypt -inkey public.pem -pubin -in plain.txt \
  63. -out plain.rsa.enc
  64. tpm2 loadexternal -G rsa -C n -p foo -r private.pem -c key.ctx
  65. tpm2 rsadecrypt -c key.ctx -p foo -o plain.rsa.dec plain.rsa.enc
  66. diff plain.txt plain.rsa.dec
  67. # try encrypting with the public key and decrypting with the private
  68. tpm2 loadexternal -G rsa -C n -p foo -u public.pem -c key.ctx
  69. tpm2 rsaencrypt -c key.ctx plain.txt -o plain.rsa.enc
  70. openssl rsautl -decrypt -inkey private.pem -in plain.rsa.enc \
  71. -out plain.rsa.dec
  72. diff plain.txt plain.rsa.dec
  73. cleanup "no-shut-down"
  74. }
  75. #
  76. # Verify loading an external AES key.
  77. #
  78. # Paramter 1: The AES keysize to create in bytes.
  79. #
  80. # Notes: Also tests that name output and YAML output are valid.
  81. #
  82. run_aes_test() {
  83. dd if=/dev/urandom of=sym.key bs=1 count=$(($1 / 8)) 2>/dev/null
  84. tpm2 loadexternal -G aes -r sym.key -n name.bin -c key.ctx > stdout.yaml
  85. local name1=$(yaml_get_kv "stdout.yaml" "name")
  86. local name2="$(xxd -c 256 -p name.bin)"
  87. test "$name1" == "$name2"
  88. echo "plaintext" > "plain.txt"
  89. if is_cmd_supported "EncryptDecrypt"; then
  90. tpm2 encryptdecrypt -c key.ctx -o plain.enc plain.txt
  91. openssl enc -in plain.enc -out plain.dec.ssl -d -K `xxd -c 256 -p sym.key` \
  92. -iv 0 -aes-$1-cfb
  93. diff plain.txt plain.dec.ssl
  94. else
  95. tpm2 readpublic -c key.ctx >out.pub
  96. alg=$(yaml_get_kv out.pub "sym-alg" "value")
  97. len=$(yaml_get_kv out.pub "sym-keybits")
  98. if [ "$alg$len" != "aes$1" ]; then
  99. echo "Algorithm parsed from tpm2 readpublic is '$alg$len' but \
  100. should be 'aes$1'"
  101. exit 1
  102. fi
  103. rm out.pub
  104. fi
  105. cleanup "no-shut-down"
  106. }
  107. run_ecc_test() {
  108. #
  109. # Test loading an OSSL PEM format ECC key, and verifying a signature
  110. # external to the TPM
  111. #
  112. #
  113. # Generate a NIST P256 Private and Public ECC pem file
  114. #
  115. openssl ecparam -name $1 -genkey -noout -out private.ecc.pem
  116. openssl ec -in private.ecc.pem -out public.ecc.pem -pubout
  117. # Generate a hash to sign
  118. echo "data to sign" > data.in.raw
  119. shasum -a 256 data.in.raw | awk '{ print "000000 " $1 }' | xxd -r -c 32 > \
  120. data.in.digest
  121. # Load the private key for signing
  122. tpm2 loadexternal -Q -G ecc -r private.ecc.pem -c key.ctx
  123. # Sign in the TPM and verify with OSSL
  124. tpm2 sign -Q -c key.ctx -g sha256 -d -f plain -o data.out.signed \
  125. data.in.digest
  126. openssl dgst -verify public.ecc.pem -keyform pem -sha256 -signature \
  127. data.out.signed data.in.raw
  128. # Sign with openssl and verify with TPM but only with the public portion of
  129. # an object loaded
  130. tpm2 loadexternal -Q -G ecc -u public.ecc.pem -c key.ctx
  131. openssl dgst -sha256 -sign private.ecc.pem -out data.out.signed data.in.raw
  132. tpm2 verifysignature -Q -c key.ctx -g sha256 -m data.in.raw -f ecdsa \
  133. -s data.out.signed
  134. cleanup "no-shut-down"
  135. }
  136. run_rsa_passin_test() {
  137. openssl genrsa -aes128 -passout "pass:mypassword" -out "private.pem" 1024
  138. if [ "$2" != "stdin" ]; then
  139. cmd="tpm2 loadexternal -Q -G rsa -r $1 -c key.ctx --passin $2"
  140. else
  141. cmd="tpm2 loadexternal -Q -G rsa -r $1 -c key.ctx --passin $2 < $3"
  142. fi;
  143. eval $cmd
  144. cleanup "no-shut-down"
  145. }
  146. run_tss_test
  147. for len in "1024 2048"; do
  148. if is_alg_supported "rsa$len"; then
  149. run_rsa_test $len
  150. fi
  151. done
  152. for len in "128 256"; do
  153. if is_alg_supported "aes$len"; then
  154. run_aes_test $len
  155. fi
  156. done
  157. if is_alg_supported "ecc256"; then
  158. run_ecc_test prime256v1
  159. fi
  160. #
  161. # Test loadexternal passin option
  162. #
  163. run_rsa_passin_test "private.pem" "pass:mypassword"
  164. export envvar="mypassword"
  165. run_rsa_passin_test "private.pem" "env:envvar"
  166. echo -n "mypassword" > "passfile"
  167. run_rsa_passin_test "private.pem" "file:passfile"
  168. echo -n "mypassword" > "passfile"
  169. exec 42<> passfile
  170. run_rsa_passin_test "private.pem" "fd:42"
  171. echo -n "mypassword" > "passfile"
  172. run_rsa_passin_test "private.pem" "stdin" "passfile"
  173. exit 0