x25519-key-agreement.sh 10 KB

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