import.sh 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. # SPDX-License-Identifier: BSD-3-Clause
  2. source helpers.sh
  3. cleanup() {
  4. rm -f import_key.ctx import_key.name import_key.priv import_key.pub \
  5. parent.ctx plain.dec.ssl plain.enc plain.txt sym.key import_rsa_key.pub \
  6. import_rsa_key.priv import_rsa_key.ctx import_rsa_key.name private.pem \
  7. public.pem plain.rsa.enc plain.rsa.dec public.pem data.in.raw \
  8. data.in.digest data.out.signed ticket.out ecc.pub ecc.priv ecc.name \
  9. ecc.ctx private.ecc.pem public.ecc.pem passfile aes.key policy.dat \
  10. aes.priv aes.pub
  11. if [ "$1" != "no-shut-down" ]; then
  12. shut_down
  13. fi
  14. }
  15. trap cleanup EXIT
  16. start_up
  17. run_aes_import_test() {
  18. dd if=/dev/urandom of=sym.key bs=1 count=$3 2>/dev/null
  19. #Symmetric Key Import Test
  20. echo "tpm2 import -Q -G aes -g "$name_alg" -i sym.key -C $1 \
  21. -u import_key.pub -r import_key.priv"
  22. tpm2 import -Q -G aes -g "$name_alg" -i sym.key -C $1 -u import_key.pub \
  23. -r import_key.priv
  24. tpm2 load -Q -C $1 -u import_key.pub -r import_key.priv -n import_key.name \
  25. -c import_key.ctx
  26. echo "plaintext" > "plain.txt"
  27. if is_cmd_supported "EncryptDecrypt"; then
  28. tpm2 encryptdecrypt -c import_key.ctx -o plain.enc plain.txt
  29. openssl enc -in plain.enc -out plain.dec.ssl -d -K `xxd -c 256 -p sym.key` \
  30. -iv 0 -$2
  31. diff plain.txt plain.dec.ssl
  32. else
  33. tpm2 readpublic -c import_key.ctx >out.pub
  34. alg=$(yaml_get_kv out.pub "sym-alg" "value")
  35. if [ "$alg" != "aes" ]; then
  36. echo "Algorithm parsed from tpm2 readpublic is '$alg' but should be \
  37. 'aes'"
  38. exit 1
  39. fi
  40. rm out.pub
  41. fi
  42. rm import_key.ctx
  43. }
  44. run_rsa_import_test() {
  45. #Asymmetric Key Import Test
  46. openssl genrsa -out private.pem $2
  47. openssl rsa -in private.pem -pubout > public.pem
  48. # Test an import without the parent public info data to force a readpublic
  49. tpm2 import -Q -G rsa -g "$name_alg" -i private.pem -C $1 \
  50. -u import_rsa_key.pub -r import_rsa_key.priv
  51. tpm2 load -Q -C $1 -u import_rsa_key.pub -r import_rsa_key.priv \
  52. -n import_rsa_key.name -c import_rsa_key.ctx
  53. openssl rsa -in private.pem -out public.pem -outform PEM -pubout
  54. openssl rsautl -encrypt -inkey public.pem -pubin -in plain.txt \
  55. -out plain.rsa.enc
  56. tpm2 rsadecrypt -c import_rsa_key.ctx -o plain.rsa.dec plain.rsa.enc
  57. diff plain.txt plain.rsa.dec
  58. # test verifying a sigature with the imported key, ie sign in tpm and
  59. # verify with openssl
  60. echo "data to sign" > data.in.raw
  61. shasum -a 256 data.in.raw | awk '{ print "000000 " $1 }' | xxd -r -c 32 > \
  62. data.in.digest
  63. tpm2 sign -Q -c import_rsa_key.ctx -g sha256 -d -f plain \
  64. -o data.out.signed data.in.digest
  65. openssl dgst -verify public.pem -keyform pem -sha256 -signature \
  66. data.out.signed data.in.raw
  67. # Sign with openssl and verify with TPM
  68. openssl dgst -sha256 -sign private.pem -out data.out.signed data.in.raw
  69. # Verify with the TPM
  70. tpm2 verifysignature -Q -c import_rsa_key.ctx -g sha256 -m data.in.raw \
  71. -f rsassa -s data.out.signed -t ticket.out
  72. rm import_rsa_key.ctx
  73. }
  74. run_ecc_import_test() {
  75. #
  76. # Test loading an OSSL PEM format ECC key, and verifying a signature
  77. # external to the TPM
  78. #
  79. #
  80. # Generate a Private and Public ECC pem file
  81. #
  82. openssl ecparam -name $2 -genkey -noout -out private.ecc.pem
  83. openssl ec -in private.ecc.pem -out public.ecc.pem -pubout
  84. # Generate a hash to sign
  85. echo "data to sign" > data.in.raw
  86. shasum -a 256 data.in.raw | awk '{ print "000000 " $1 }' | xxd -r -c 32 > \
  87. data.in.digest
  88. tpm2 import -Q -G ecc -g "$name_alg" -i private.ecc.pem -C $1 -u ecc.pub \
  89. -r ecc.priv
  90. tpm2 load -Q -C $1 -u ecc.pub -r ecc.priv -n ecc.name -c ecc.ctx
  91. # Sign in the TPM and verify with OSSL
  92. tpm2 sign -Q -c ecc.ctx -g sha256 -d -f plain -o data.out.signed \
  93. data.in.digest
  94. openssl dgst -verify public.ecc.pem -keyform pem -sha256 \
  95. -signature data.out.signed data.in.raw
  96. # Sign with openssl and verify with TPM.
  97. openssl dgst -sha256 -sign private.ecc.pem -out data.out.signed data.in.raw
  98. tpm2 verifysignature -Q -c ecc.ctx -g sha256 -m data.in.raw -f ecdsa \
  99. -s data.out.signed
  100. rm ecc.ctx
  101. }
  102. run_rsa_import_passin_test() {
  103. if [ "$3" != "stdin" ]; then
  104. tpm2 import -Q -G rsa -i "$2" -C "$1" \
  105. -u "import_rsa_key.pub" -r "import_rsa_key.priv" \
  106. --passin "$3"
  107. else
  108. tpm2 import -Q -G rsa -i "$2" -C "$1" \
  109. -u "import_rsa_key.pub" -r "import_rsa_key.priv" \
  110. --passin "$3" < "$4"
  111. fi;
  112. }
  113. run_aes_policy_import_test() {
  114. dd if=/dev/urandom of=aes.key bs=16 count=1
  115. dd if=/dev/urandom of=policy.dat bs=32 count=1
  116. tpm2 import -C "$1" -G aes -i aes.key -L policy.dat -u aes.pub -r aes.priv
  117. tpm2 load -C "$1" -u aes.priv -u aes.pub -r aes.priv -c aes.ctx
  118. trap - ERR
  119. echo 'foo' | tpm2 encryptdecrypt -c aes.ctx -o plain.rsa.dec plain.rsa.enc
  120. if [ $? -eq 0 ]; then
  121. echo "expected tpm2 encryptdecrypt to fail"
  122. exit 1
  123. fi
  124. trap onerror ERR
  125. }
  126. run_test() {
  127. cleanup "no-shut-down"
  128. parent_alg=$1
  129. name_alg=$2
  130. tpm2 createprimary -Q -G "$parent_alg" -g "$name_alg" -C o -c parent.ctx
  131. # 128 bit AES is 16 bytes
  132. if is_alg_supported aes128; then
  133. run_aes_import_test parent.ctx aes-128-cfb 16
  134. fi
  135. # 256 bit AES is 32 bytes
  136. if is_alg_supported aes256; then
  137. run_aes_import_test parent.ctx aes-256-cfb 32
  138. fi
  139. run_rsa_import_test parent.ctx 1024
  140. run_rsa_import_test parent.ctx 2048
  141. run_ecc_import_test parent.ctx prime256v1
  142. }
  143. #
  144. # Run the tests against:
  145. # - RSA2048 with AES CFB 128 and 256 bit parents
  146. # - SHA256 object (not parent) name algorithms
  147. #
  148. parent_algs=("rsa2048:aes128cfb" "rsa2048:aes256cfb" "ecc256:aes128cfb")
  149. halgs=`populate_hash_algs 'and alg != "sha1"'`
  150. echo "halgs: $halgs"
  151. for pa in "${parent_algs[@]}"; do
  152. for name in $halgs; do
  153. if is_alg_supported $pa; then
  154. echo "$pa - $name"
  155. run_test "$pa" "$name"
  156. fi
  157. done;
  158. done;
  159. #
  160. # Test the passin options
  161. #
  162. tpm2 createprimary -Q -c parent.ctx
  163. openssl genrsa -aes128 -passout "pass:mypassword" -out "private.pem" 1024
  164. run_rsa_import_passin_test "parent.ctx" "private.pem" "pass:mypassword"
  165. export envvar="mypassword"
  166. run_rsa_import_passin_test "parent.ctx" "private.pem" "env:envvar"
  167. echo -n "mypassword" > "passfile"
  168. run_rsa_import_passin_test "parent.ctx" "private.pem" "file:passfile"
  169. exec 42<> passfile
  170. run_rsa_import_passin_test "parent.ctx" "private.pem" "fd:42"
  171. run_rsa_import_passin_test "parent.ctx" "private.pem" "stdin" "passfile"
  172. run_aes_policy_import_test "parent.ctx"
  173. exit 0