dh-key-agreement.sh 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  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. DH key exchange, matching private key public peer key (openssl, openssl)
  20. # 2. DH key exchange, matching private key public peer key (engine, engine)
  21. #
  22. # Setup:
  23. # 1. Configure the openssl: export OPENSSL_DIR="/path/to/openssl-1.1.1k"
  24. # 2. Set engine path: export OPENSSL_ENGINES=/path/to/engines
  25. #
  26. # Usage:
  27. # run all tests: bash dh-key-agreement.sh
  28. # run a test: bash dh-key-agreement.sh <test number>
  29. #
  30. # Date: 12/8/2021
  31. ##############################################################################
  32. ############################ constants ############################
  33. PASS=0
  34. FAIL=1
  35. DEBUG=false
  36. VALIDATE_SETUP=true
  37. ENGINE_ID_28=eip28pka
  38. KERNEL_MODULE=umpci_k
  39. OPENSSL=$OPENSSL_DIR/apps/openssl
  40. DATESTAMP=$(date +%y%m%d_%H%M)
  41. TEMPFILE=tempfile.txt
  42. VALGRIND_CMD='valgrind --leak-check=full --show-leak-kinds=all --log-file='$TEMPFILE
  43. ############################ functions ############################
  44. print_function() {
  45. echo "${FUNCNAME[1]}"
  46. }
  47. print_openssl_details() {
  48. [ $DEBUG = true ] && print_function
  49. ${OPENSSL} version
  50. }
  51. validate_environment() {
  52. [ $DEBUG = true ] && print_function
  53. if [ -z $OPENSSL_DIR ]; then
  54. echo "Error: Environment variable OPENSSL_DIR is undefined"
  55. return $FAIL
  56. fi
  57. if [ ! -f $OPENSSL_DIR/apps/openssl ]; then
  58. echo "Error: openssl client not found"
  59. return $FAIL
  60. fi
  61. if [ -z $OPENSSL_ENGINES ]; then
  62. echo "Error: Environment variable OPENSSL_ENGINES is undefined"
  63. return $FAIL
  64. fi
  65. if [ $(lsmod | grep "$KERNEL_MODULE" -c) -ne 1 ]; then
  66. echo "Error: kernel module $KERNEL_MODULE not found"
  67. return $FAIL
  68. fi
  69. return $PASS
  70. }
  71. print_engine_capabilities() {
  72. [ $DEBUG = true ] && print_function
  73. ${OPENSSL} engine -c $ENGINE_ID_28
  74. }
  75. is_engine_available() {
  76. if [ $(${OPENSSL} engine -t eip28pka | grep -c "\[ available \]") -ne 1 ]; then
  77. echo "Error: engine unavailable"
  78. return $FAIL
  79. fi
  80. return $PASS
  81. }
  82. print_configuration() {
  83. echo "DEBUG $DEBUG "
  84. echo "VALIDATE_SETUP $VALIDATE_SETUP"
  85. echo "ENGINE_ID_28 $ENGINE_ID_28 "
  86. echo "KERNEL_MODULE $KERNEL_MODULE "
  87. echo "OPENSSL $OPENSSL "
  88. }
  89. create_test_file() {
  90. local filename=$1
  91. local length=$2
  92. [ $DEBUG = true ] && print_function
  93. echo $(${OPENSSL} rand -base64 $length) > $filename
  94. [ $DEBUG = true ] && cat $filename
  95. }
  96. create_dh_key_params() {
  97. [ $DEBUG = true ] && print_function
  98. local engine=$1
  99. local dh_key_params_file=$2
  100. local parameter_engine
  101. [ $engine == true ] && parameter_engine=-engine=$ENGINE_ID_28
  102. local ret
  103. local print
  104. # create key params:
  105. # openssl genpkey -genparam -algorithm DH -out dhp.pem
  106. # examine key params:
  107. # openssl pkeyparam -in dhp.pem -text
  108. print=`${OPENSSL} genpkey \
  109. -genparam \
  110. $parameter_engine \
  111. -algorithm DH \
  112. -out $dh_key_params_file 2>&1`
  113. ret=$?
  114. [ $DEBUG = true ] && echo "$print"
  115. [ $DEBUG = true ] && echo "return: $ret"
  116. return $ret
  117. }
  118. create_dh_private_key() {
  119. [ $DEBUG = true ] && print_function
  120. local engine=$1
  121. local dh_key_params_file=$2
  122. local private_key_file=$3
  123. local parameter_engine
  124. [ $engine == true ] && parameter_engine=-engine=$ENGINE_ID_28
  125. local ret
  126. local print
  127. # generate private DH key:
  128. # openssl genpkey -paramfile dhp.pem -out dhkey1.pem
  129. # examine private key:
  130. # openssl pkey -in dhkey2.pem -text -noout
  131. print=`${OPENSSL} genpkey \
  132. $parameter_engine \
  133. -paramfile $dh_key_params_file \
  134. -out $private_key_file 2>&1`
  135. ret=$?
  136. [ $DEBUG = true ] && echo "$print"
  137. [ $DEBUG = true ] && echo "return: $ret"
  138. [ $DEBUG = true ] && cat $private_key_file
  139. return $ret
  140. }
  141. derive_public_key() {
  142. [ $DEBUG = true ] && print_function
  143. local engine=$1
  144. local private_key_file=$2
  145. local public_key_file=$3
  146. local parameter_engine
  147. [ $engine == true ] && parameter_engine=-engine=$ENGINE_ID_28
  148. local ret
  149. local print
  150. # generate public key:
  151. # openssl pkey -in dhkey1.pem -pubout -out dhpub1.pem
  152. # examine public key:
  153. # openssl pkey -pubin -in dhpub1.pem -text
  154. print=`${OPENSSL} pkey \
  155. $parameter_engine \
  156. -in $private_key_file \
  157. -pubout \
  158. -out $public_key_file 2>&1`
  159. ret=$?
  160. [ $DEBUG = true ] && echo "return: $ret"
  161. [ $DEBUG = true ] && cat $public_key_file
  162. return $ret
  163. }
  164. derive_shared_secret() {
  165. [ $DEBUG = true ] && print_function
  166. local engine=$1
  167. local private_key_file=$2
  168. local public_key_peer_file=$3
  169. local output_secert_file=$4
  170. local ret
  171. local print
  172. local parameter_engine
  173. if [ $engine == true ]; then
  174. local valgrind=$VALGRIND
  175. local dovalgrind=$DO_VALGRIND
  176. fi
  177. if [ $dovalgrind ]; then
  178. echo "// derive_shared_secret $2 $3 $4" >> dh-key-agreement_$DATESTAMP.log
  179. fi
  180. [ $engine == true ] && parameter_engine=-engine=$ENGINE_ID_28
  181. # openssl pkeyutl -derive -inkey alice.pem -peerkey bob.pub -out alicebob.key
  182. print=`$valgrind $OPENSSL pkeyutl \
  183. -derive \
  184. $parameter_engine \
  185. -inkey $private_key_file \
  186. -peerkey $public_key_peer_file \
  187. -out $output_secert_file 2>&1`
  188. ret=$?
  189. [ $DEBUG = true ] && echo "*********************** START *******************************"
  190. [ $DEBUG = true ] && echo "$print"
  191. [ $DEBUG = true ] && echo "*********************** END *******************************"
  192. [ $DEBUG = true ] && echo "return: $ret"
  193. if [ $dovalgrind ]; then
  194. cat $TEMPFILE >> dh-key-agreement_$DATESTAMP.log
  195. fi
  196. return $ret
  197. }
  198. cleanup() {
  199. [ $DEBUG = true ] && print_function
  200. for f in "$@"; do
  201. [ -f "$f" ] && rm $f
  202. done
  203. }
  204. test_dh_key_exchange_positive() {
  205. local use_engine_1=$1
  206. local use_engine_2=$2
  207. cleanup key_params.pem private1.pem public1.pem private2.pem public2.pem secret1.bin secret2.bin
  208. create_dh_key_params false key_params.pem
  209. [ $? -ne 0 ] && return 1
  210. create_dh_private_key false key_params.pem private1.pem
  211. [ $? -ne 0 ] && return 2
  212. derive_public_key false private1.pem public1.pem
  213. [ $? -ne 0 ] && return 3
  214. create_dh_private_key false key_params.pem private2.pem
  215. [ $? -ne 0 ] && return 4
  216. derive_public_key false private2.pem public2.pem
  217. [ $? -ne 0 ] && return 5
  218. derive_shared_secret $use_engine_1 private1.pem public2.pem secret1.bin
  219. [ $? -ne 0 ] && return 6
  220. derive_shared_secret $use_engine_2 private2.pem public1.pem secret2.bin
  221. [ $? -ne 0 ] && return 7
  222. cmp -s secret1.bin secret2.bin
  223. [ $? -ne 0 ] && return 8
  224. return $PASS
  225. }
  226. test_dh_key_exchange_negative() {
  227. local use_engine_1=$1
  228. local use_engine_2=$2
  229. cleanup private1.pem public1.pem private2.pem public2.pem secret1.bin secret2.bin
  230. create_EC_private_key false P-256 private1.pem
  231. [ $? -ne 0 ] && return 1
  232. derive_public_key false private1.pem public1.pem
  233. [ $? -ne 0 ] && return 2
  234. create_EC_private_key false P-256 private2.pem
  235. [ $? -ne 0 ] && return 3
  236. derive_public_key false private2.pem public2.pem
  237. [ $? -ne 0 ] && return 4
  238. create_EC_private_key false P-256 private3.pem
  239. [ $? -ne 0 ] && return 5
  240. derive_public_key false private3.pem public3.pem
  241. [ $? -ne 0 ] && return 6
  242. derive_shared_secret $use_engine_1 private1.pem public2.pem secret1.bin
  243. [ $? -ne 0 ] && return 7
  244. derive_shared_secret $use_engine_2 private2.pem public3.pem secret2.bin
  245. [ $? -ne 0 ] && return 8
  246. cmp -s secret1.bin secret2.bin
  247. [ $? -eq 0 ] && return 6
  248. return $PASS
  249. }
  250. ############################ main ############################
  251. main () {
  252. echo "Test: DH key agreement"
  253. # arguments
  254. run_all=false
  255. run_test_number=0
  256. if [ "$1" -eq "$1" ] 2>/dev/null; then
  257. run_test_number=$1
  258. echo "Run test number $test_number"
  259. else
  260. run_all=true
  261. echo "Run all tests"
  262. fi
  263. # validation
  264. if [ $VALIDATE_SETUP == true ]; then
  265. echo "validate setup"
  266. validate_environment
  267. [ $? -eq $FAIL ] && exit 1
  268. is_engine_available
  269. [ $? -eq $FAIL ] && exit 1
  270. print_configuration
  271. print_openssl_details
  272. print_engine_capabilities
  273. fi
  274. if [ "$1" = "-v" ] || [ "$2" = "-v" ]; then
  275. DO_VALGRIND=1
  276. VALGRIND=$VALGRIND_CMD
  277. echo "// OS_IK dh-key-agreement valgrind results - $DATESTAMP" > dh-key-agreement_$DATESTAMP.log
  278. fi
  279. # tests:
  280. tests_run=0
  281. tests_pass=0
  282. tests_total=3
  283. if [ $run_all == true ] || [ $run_test_number -eq 1 ]; then
  284. test_name="DH key exchange, matching private key public peer key (openssl, openssl)"
  285. printf "Test %s: " "$test_name"
  286. test_dh_key_exchange_positive false false
  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 2 ]; then
  293. test_name="DH key exchange, matching private key public peer key (engine, engine)"
  294. printf "Test %s: " "$test_name"
  295. test_dh_key_exchange_positive true true
  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 3 ]; then
  302. test_name="DH key exchange, matching private key public peer key (openssl, engine)"
  303. printf "Test %s: " "$test_name"
  304. test_dh_key_exchange_positive false true
  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 "$@"