ecdh-key-agreement.sh 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. #!/bin/bash
  2. ##############################################################################
  3. # Copyright (c) 2021 by Rambus, Inc. and/or its subsidiaries
  4. # All rights reserved. Unauthorized use (including, without limitation,
  5. # distribution and copying) is strictly prohibited. All use requires,
  6. # and is subject to, explicit written authorization and nondisclosure
  7. # Rambus, Inc. and/or its subsidiaries
  8. #
  9. # For more information or support, please go to our online support system at
  10. # https://sipsupport.rambus.com.
  11. # In case you do not have an account for this system, please send an e-mail
  12. # to sipsupport@rambus.com.
  13. ##############################################################################
  14. #
  15. # This script tests openssl engine e_eip28pka.so with openssl 1.1.1k
  16. # running on an x86 host and a PCIe virtex HW with the PKA module.
  17. #
  18. # Tests:
  19. # 1. ECDH key exchange, curve P-256, matching private key public peer key (openssl, openssl)
  20. # 2. ECDH key exchange, curve P-256, matching private key public peer key P-256 (engine, engine)
  21. # 3. ECDH key exchange, curve P-256, matching private key public peer key P-256 (openssl, engine)
  22. # 4. ECDH key exchange, curve P-256, unmatching private key public peer key P-256 (openssl, openssl)
  23. # 5. ECDH key exchange, curve P-256, unmatching private key public peer key P-256 (openssl, engine)
  24. #
  25. # Setup:
  26. # 1. Configure the openssl: export OPENSSL_DIR="/path/to/openssl-1.1.1k"
  27. # 2. Set engine path: export OPENSSL_ENGINES=/path/to/engines
  28. #
  29. # Usage:
  30. # run all tests: bash ecdh-key-agreement.sh
  31. # run a test: bash ecdh-key-agreement.sh <test number>
  32. #
  33. # Date: 12/8/2021
  34. ##############################################################################
  35. ############################ constants ############################
  36. PASS=0
  37. FAIL=1
  38. DEBUG=false
  39. VALIDATE_SETUP=true
  40. ENGINE_ID_28=eip28pka
  41. KERNEL_MODULE=umpci_k
  42. OPENSSL=$OPENSSL_DIR/apps/openssl
  43. DATESTAMP=$(date +%y%m%d_%H%M)
  44. TEMPFILE=tempfile.txt
  45. VALGRIND_CMD='valgrind --leak-check=full --show-leak-kinds=all --log-file='$TEMPFILE
  46. ############################ functions ############################
  47. print_function() {
  48. echo "${FUNCNAME[1]}"
  49. }
  50. print_openssl_details() {
  51. [ $DEBUG = true ] && print_function
  52. ${OPENSSL} version
  53. }
  54. validate_environment() {
  55. [ $DEBUG = true ] && print_function
  56. if [ -z $OPENSSL_DIR ]; then
  57. echo "Error: Environment variable OPENSSL_DIR is undefined"
  58. return $FAIL
  59. fi
  60. if [ ! -f $OPENSSL_DIR/apps/openssl ]; then
  61. echo "Error: openssl client not found"
  62. return $FAIL
  63. fi
  64. if [ -z $OPENSSL_ENGINES ]; then
  65. echo "Error: Environment variable OPENSSL_ENGINES is undefined"
  66. return $FAIL
  67. fi
  68. if [ $(lsmod | grep "$KERNEL_MODULE" -c) -ne 1 ]; then
  69. echo "Error: kernel module $KERNEL_MODULE not found"
  70. return $FAIL
  71. fi
  72. return $PASS
  73. }
  74. print_engine_capabilities() {
  75. [ $DEBUG = true ] && print_function
  76. ${OPENSSL} engine -c $ENGINE_ID_28
  77. }
  78. is_engine_available() {
  79. if [ $(${OPENSSL} engine -t eip28pka | grep -c "\[ available \]") -ne 1 ]; then
  80. echo "Error: engine unavailable"
  81. return $FAIL
  82. fi
  83. return $PASS
  84. }
  85. print_configuration() {
  86. echo "DEBUG $DEBUG "
  87. echo "VALIDATE_SETUP $VALIDATE_SETUP"
  88. echo "ENGINE_ID_28 $ENGINE_ID_28 "
  89. echo "KERNEL_MODULE $KERNEL_MODULE "
  90. echo "OPENSSL $OPENSSL "
  91. }
  92. create_test_file() {
  93. local filename=$1
  94. local length=$2
  95. [ $DEBUG = true ] && print_function
  96. echo $(${OPENSSL} rand -base64 $length) > $filename
  97. [ $DEBUG = true ] && cat $filename
  98. }
  99. create_EC_private_key() {
  100. [ $DEBUG = true ] && print_function
  101. local engine=$1
  102. local curve=$2
  103. local private_key_file=$3
  104. local parameter_engine
  105. [ $engine == true ] && parameter_engine=-engine=$ENGINE_ID_28
  106. local ret
  107. local print
  108. # generate private key:
  109. # openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out private.pem
  110. # examine private key:
  111. # openssl ec -in private.pem -noout -text
  112. print=`${OPENSSL} genpkey \
  113. $parameter_engine \
  114. -algorithm EC \
  115. -pkeyopt ec_paramgen_curve:$curve \
  116. -out $private_key_file 2>&1`
  117. ret=$?
  118. [ $DEBUG = true ] && echo "$print"
  119. [ $DEBUG = true ] && echo "return: $ret"
  120. [ $DEBUG = true ] && cat $private_key_file
  121. return $ret
  122. }
  123. derive_public_key() {
  124. [ $DEBUG = true ] && print_function
  125. local engine=$1
  126. local private_key_file=$2
  127. local public_key_file=$3
  128. local parameter_engine
  129. [ $engine == true ] && parameter_engine=-engine=$ENGINE_ID_28
  130. local ret
  131. local print
  132. # generate public key:
  133. # openssl ec -pubout -in private.pem -out public.pem
  134. # examine public key:
  135. # openssl pkey -noout -text -inform PEM -in public.pem -pubin
  136. print=`${OPENSSL} pkey \
  137. $parameter_engine \
  138. -pubout \
  139. -in $private_key_file \
  140. -out $public_key_file 2>&1`
  141. ret=$?
  142. [ $DEBUG = true ] && echo "return: $ret"
  143. [ $DEBUG = true ] && cat $public_key_file
  144. return $ret
  145. }
  146. derive_shared_secret() {
  147. [ $DEBUG = true ] && print_function
  148. local engine=$1
  149. local private_key_file=$2
  150. local public_key_peer_file=$3
  151. local output_secert_file=$4
  152. local ret
  153. local print
  154. local parameter_engine
  155. if [ $engine == true ]; then
  156. local valgrind=$VALGRIND
  157. local dovalgrind=$DO_VALGRIND
  158. fi
  159. if [ $dovalgrind ]; then
  160. echo "// derive_shared_secret $2 $3 $4" >> ecdh-key-agreement_$DATESTAMP.log
  161. fi
  162. [ $engine == true ] && parameter_engine=-engine=$ENGINE_ID_28
  163. # openssl pkeyutl -derive -inkey alice.pem -peerkey bob.pub -out alicebob.key
  164. print=`$valgrind $OPENSSL pkeyutl \
  165. -derive \
  166. $parameter_engine \
  167. -inkey $private_key_file \
  168. -peerkey $public_key_peer_file \
  169. -out $output_secert_file 2>&1`
  170. ret=$?
  171. [ $DEBUG = true ] && echo "*********************** START *******************************"
  172. [ $DEBUG = true ] && echo "$print"
  173. [ $DEBUG = true ] && echo "*********************** END *******************************"
  174. [ $DEBUG = true ] && echo "return: $ret"
  175. if [ $dovalgrind ]; then
  176. cat $TEMPFILE >> ecdh-key-agreement_$DATESTAMP.log
  177. fi
  178. return $ret
  179. }
  180. cleanup() {
  181. [ $DEBUG = true ] && print_function
  182. for f in "$@"; do
  183. [ -f "$f" ] && rm $f
  184. done
  185. }
  186. test_ecdh_key_exchange_positive() {
  187. local use_engine_1=$1
  188. local use_engine_2=$2
  189. local curve=$3
  190. cleanup private1.pem public1.pem private2.pem public2.pem secret1.bin secret2.bin
  191. create_EC_private_key false $curve private1.pem
  192. [ $? -ne 0 ] && return 1
  193. derive_public_key false private1.pem public1.pem
  194. [ $? -ne 0 ] && return 2
  195. create_EC_private_key false $curve private2.pem
  196. [ $? -ne 0 ] && return 3
  197. derive_public_key false private2.pem public2.pem
  198. [ $? -ne 0 ] && return 4
  199. derive_shared_secret $use_engine_1 private1.pem public2.pem secret1.bin
  200. [ $? -ne 0 ] && return 5
  201. derive_shared_secret $use_engine_2 private2.pem public1.pem secret2.bin
  202. [ $? -ne 0 ] && return 5
  203. cmp -s secret1.bin secret2.bin
  204. [ $? -ne 0 ] && return 5
  205. return $PASS
  206. }
  207. test_ecdh_key_exchange_negative() {
  208. local use_engine_1=$1
  209. local use_engine_2=$2
  210. local curve=$3
  211. cleanup private1.pem public1.pem private2.pem public2.pem secret1.bin secret2.bin
  212. create_EC_private_key false $curve private1.pem
  213. [ $? -ne 0 ] && return 1
  214. derive_public_key false private1.pem public1.pem
  215. [ $? -ne 0 ] && return 2
  216. create_EC_private_key false $curve private2.pem
  217. [ $? -ne 0 ] && return 3
  218. derive_public_key false private2.pem public2.pem
  219. [ $? -ne 0 ] && return 4
  220. create_EC_private_key false $curve private3.pem
  221. [ $? -ne 0 ] && return 5
  222. derive_public_key false private3.pem public3.pem
  223. [ $? -ne 0 ] && return 6
  224. derive_shared_secret $use_engine_1 private1.pem public2.pem secret1.bin
  225. [ $? -ne 0 ] && return 7
  226. derive_shared_secret $use_engine_2 private2.pem public3.pem secret2.bin
  227. [ $? -ne 0 ] && return 8
  228. cmp -s secret1.bin secret2.bin
  229. [ $? -eq 0 ] && return 6
  230. return $PASS
  231. }
  232. ############################ main ############################
  233. main () {
  234. echo "Test: ECDH key agreement"
  235. # arguments
  236. run_all=false
  237. run_test_number=0
  238. if [ "$1" -eq "$1" ] 2>/dev/null; then
  239. run_test_number=$1
  240. echo "Run test number $test_number"
  241. else
  242. run_all=true
  243. echo "Run all tests"
  244. fi
  245. # validation
  246. if [ $VALIDATE_SETUP == true ]; then
  247. echo "validate setup"
  248. validate_environment
  249. [ $? -eq $FAIL ] && exit 1
  250. is_engine_available
  251. [ $? -eq $FAIL ] && exit 1
  252. print_configuration
  253. print_openssl_details
  254. print_engine_capabilities
  255. fi
  256. if [ "$1" = "-v" ] || [ "$2" = "-v" ]; then
  257. DO_VALGRIND=1
  258. VALGRIND=$VALGRIND_CMD
  259. echo "// OS_IK ecdh-key-agreement valgrind results - $DATESTAMP" > ecdh-key-agreement_$DATESTAMP.log
  260. fi
  261. # tests:
  262. tests_run=0
  263. tests_pass=0
  264. tests_total=5
  265. if [ $run_all == true ] || [ $run_test_number -eq 1 ]; then
  266. test_name="ECDH key exchange, curve P-256, matching private key public peer key (openssl, openssl)"
  267. printf "Test %s: " "$test_name"
  268. test_ecdh_key_exchange_positive false false P-256
  269. result=$?
  270. [ $result -eq $PASS ] && echo "PASSED" || echo "FAILED ($result)"
  271. if [ $result -eq $PASS ]; then (( tests_pass++ )); fi
  272. (( tests_run++ ))
  273. fi
  274. if [ $run_all == true ] || [ $run_test_number -eq 2 ]; then
  275. test_name="ECDH key exchange, curve P-256, matching private key public peer key (engine, engine)"
  276. printf "Test %s: " "$test_name"
  277. test_ecdh_key_exchange_positive true true P-256
  278. result=$?
  279. [ $result -eq $PASS ] && echo "PASSED" || echo "FAILED ($result)"
  280. if [ $result -eq $PASS ]; then (( tests_pass++ )); fi
  281. (( tests_run++ ))
  282. fi
  283. if [ $run_all == true ] || [ $run_test_number -eq 3 ]; then
  284. test_name="ECDH key exchange, curve P-256, matching private key public peer key (openssl, engine)"
  285. printf "Test %s: " "$test_name"
  286. test_ecdh_key_exchange_positive false true P-256
  287. result=$?
  288. [ $result -eq $PASS ] && echo "PASSED" || echo "FAILED ($result)"
  289. if [ $result -eq $PASS ]; then (( tests_pass++ )); fi
  290. (( tests_run++ ))
  291. fi
  292. if [ $run_all == true ] || [ $run_test_number -eq 4 ]; then
  293. test_name="ECDH key exchange, curve P-256, unmatching private key public peer key (openssl, openssl)"
  294. printf "Test %s: " "$test_name"
  295. test_ecdh_key_exchange_negative false false P-256
  296. result=$?
  297. [ $result -eq $PASS ] && echo "PASSED" || echo "FAILED ($result)"
  298. if [ $result -eq $PASS ]; then (( tests_pass++ )); fi
  299. (( tests_run++ ))
  300. fi
  301. if [ $run_all == true ] || [ $run_test_number -eq 5 ]; then
  302. test_name="ECDH key exchange, curve P-256, unmatching private key public peer key (openssl, engine)"
  303. printf "Test %s: " "$test_name"
  304. test_ecdh_key_exchange_negative false true P-256
  305. result=$?
  306. [ $result -eq $PASS ] && echo "PASSED" || echo "FAILED ($result)"
  307. if [ $result -eq $PASS ]; then (( tests_pass++ )); fi
  308. (( tests_run++ ))
  309. fi
  310. echo "tests: $tests_total run: $tests_run passed: $tests_pass"
  311. if [ $DO_VALGRIND ]; then
  312. rm $TEMPFILE
  313. fi
  314. exit 0
  315. }
  316. main "$@"