Vboot Reference: Add a RSA verify benchmark.

In addtion, add test cases and a script to generate them for benchmarking. Also fixes a path problem with the run_rsa_tests.sh script.

Review URL: http://codereview.chromium.org/626011
diff --git a/tests/Makefile b/tests/Makefile
index 5d4faf9..cd47d22 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -7,10 +7,10 @@
 INCLUDES ?= -I../include/
 TOP ?= ../
 
-LIBS = $(TOP)/utils/firmware_image.o $(TOP)/crypto/libcrypto.a $(TOP)/common/libcommon.a  \
-	$(TOP)/utils/file_keys.o -lrt
+LIBS = $(TOP)/utils/firmware_image.o $(TOP)/crypto/libcrypto.a \
+	$(TOP)/common/libcommon.a $(TOP)/utils/file_keys.o -lrt
 
-tests: firmware_image_tests sha_tests sha_benchmark
+tests: firmware_image_tests sha_tests sha_benchmark rsa_verify_benchmark
 
 sha_tests: sha_tests.c
 	$(CC) $(CFLAGS) $(INCLUDES) $< -o $@ $(LIBS)
@@ -21,5 +21,8 @@
 sha_benchmark:	sha_benchmark.c timer_utils.c
 	$(CC) $(CFLAGS) $(INCLUDES) $^ -o $@ $(LIBS)
 
+rsa_verify_benchmark: rsa_verify_benchmark.c timer_utils.c
+	$(CC) $(CFLAGS) $(INCLUDES) $^ -o $@ $(LIBS)
+
 clean:
-	rm -f sha_tests sha_benchmark firmware_image_tests
+	rm -f sha_tests sha_benchmark rsa_verify_benchmark firmware_image_tests
diff --git a/tests/gen_test_cases.sh b/tests/gen_test_cases.sh
new file mode 100755
index 0000000..b15921d
--- /dev/null
+++ b/tests/gen_test_cases.sh
@@ -0,0 +1,54 @@
+#!/bin/bash
+
+# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Generate test cases for use for the RSA verify benchmark.
+
+KEY_DIR=testkeys
+TESTCASE_DIR=testcases
+UTIL_DIR=../utils/
+TEST_FILE=test_file 
+TEST_FILE_SIZE=1000000
+
+hash_algos=( sha1 sha256 sha512 )
+key_lengths=( 1024 2048 4096 8192 ) 
+
+# Generate public key signatures and digest on an input file for 
+# various combinations of message digest algorithms and RSA key sizes.
+function generate_test_signatures {
+  algorithmcounter=0
+  for keylen in ${key_lengths[@]}
+  do
+    for hashalgo in ${hash_algos[@]}
+    do
+      openssl dgst -${hashalgo} -binary -out $1.${hashalgo}.digest $1
+      ${UTIL_DIR}/signature_digest $algorithmcounter $1 | openssl rsautl -sign \
+        -pkcs -inkey ${KEY_DIR}/key_rsa${keylen}.pem \
+        > $1.rsa${keylen}_${hashalgo}.sig
+      let algorithmcounter=algorithmcounter+1
+    done
+  done
+}
+
+function pre_work {
+  # Generate a file with random bytes for signature tests.
+  echo "Generating test file..."
+  dd if=/dev/urandom of=${TESTCASE_DIR}/${TEST_FILE} bs=${TEST_FILE_SIZE} count=1
+}
+
+if [ ! -d "$KEY_DIR" ]
+then
+  echo "You must run gen_test_cases.sh to generate test keys first."
+  exit 1
+fi
+
+if [ ! -d "$TESTCASE_DIR" ]
+then
+  mkdir  "$TESTCASE_DIR"
+fi
+
+pre_work
+echo "Generating test signatures..."
+generate_test_signatures ${TESTCASE_DIR}/$TEST_FILE
diff --git a/tests/rsa_verify_benchmark.c b/tests/rsa_verify_benchmark.c
new file mode 100644
index 0000000..a728426
--- /dev/null
+++ b/tests/rsa_verify_benchmark.c
@@ -0,0 +1,87 @@
+/* Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "file_keys.h"
+#include "padding.h"
+#include "rsa.h"
+#include "timer_utils.h"
+#include "utility.h"
+
+#define FILE_NAME_SIZE 128
+#define NUM_OPERATIONS 100 /* Number of signature operations to time. */
+
+void SpeedTestAlgorithm(int algorithm) {
+  int i, key_size;
+  double speed, msecs;
+  char file_name[FILE_NAME_SIZE];
+  uint8_t* digest = NULL;
+  uint8_t* signature = NULL;
+  int digest_len;
+  int sig_len;
+  RSAPublicKey* key = NULL;
+  ClockTimerState ct;
+  char* sha_strings[] = {  /* Maps algorithm->SHA algorithm. */
+    "sha1", "sha256", "sha512",  /* RSA-1024 */
+    "sha1", "sha256", "sha512",  /* RSA-2048 */
+    "sha1", "sha256", "sha512",  /* RSA-4096 */
+    "sha1", "sha256", "sha512",  /* RSA-8192 */
+  };
+
+  key_size = siglen_map[algorithm] * sizeof(uint32_t) * 8;  /* in bits. */
+  /* Get key. */
+  snprintf(file_name, FILE_NAME_SIZE, "testkeys/key_rsa%d.keyb", key_size);
+  key = RSAPublicKeyFromFile(file_name);
+  if (!key) {
+    fprintf(stderr, "Couldn't read key from file.\n");
+    goto failure;
+  }
+
+  /* Get expected digest. */
+  snprintf(file_name, FILE_NAME_SIZE, "testcases/test_file.%s.digest",
+           sha_strings[algorithm]);
+  digest = BufferFromFile(file_name, &digest_len);
+  if (!digest) {
+    fprintf(stderr, "Couldn't read digest file.\n");
+    goto failure;
+  }
+
+  /* Get signature to verify against. */
+  snprintf(file_name, FILE_NAME_SIZE, "testcases/test_file.rsa%d_%s.sig",
+           key_size, sha_strings[algorithm]);
+  signature = BufferFromFile(file_name, &sig_len);
+  if (!signature) {
+    fprintf(stderr, "Couldn't read signature file.\n");
+    goto failure;
+  }
+
+  StartTimer(&ct);
+  for (i = 0; i < NUM_OPERATIONS; i++) {
+    if (!RSA_verify(key, signature, sig_len, algorithm, digest))
+      fprintf(stderr, "Warning: Signature Check Failed.\n");
+  }
+  StopTimer(&ct);
+
+  msecs = (float) GetDurationMsecs(&ct) / NUM_OPERATIONS;
+  speed = 1000.0 / msecs ;
+  fprintf(stderr, "rsa%d/%s bits:\tTime taken per verification = %.02f ms,"
+          " Speed = %.02f verifications/s\n", key_size, sha_strings[algorithm],
+          msecs, speed);
+
+failure:
+  Free(signature);
+  Free(digest);
+  Free(key);
+}
+
+int main(int argc, char* argv[]) {
+  int i;
+  for (i = 0; i < kNumAlgorithms; ++i) {
+    SpeedTestAlgorithm(i);
+  }
+  return 0;
+}
diff --git a/tests/run_rsa_tests.sh b/tests/run_rsa_tests.sh
index 2038483..2aa7426 100755
--- a/tests/run_rsa_tests.sh
+++ b/tests/run_rsa_tests.sh
@@ -55,9 +55,11 @@
     for hashalgo in ${hash_algos[@]}
     do
       echo -e "For ${COL_YELLOW}RSA-$keylen and $hashalgo${COL_STOP}:"
-      cd ${UTIL_DIR} && ${TEST_DIR}/firmware_image_tests $algorithmcounter testkeys/key_rsa8192.pem \
-        testkeys/key_rsa8192.keyb testkeys/key_rsa${keylen}.pem \
-        testkeys/key_rsa${keylen}.keyb
+      cd ${UTIL_DIR} && ${TEST_DIR}/firmware_image_tests $algorithmcounter \
+        ${TEST_DIR}/testkeys/key_rsa8192.pem \
+        ${TEST_DIR}/testkeys/key_rsa8192.keyb \
+        ${TEST_DIR}/testkeys/key_rsa${keylen}.pem \
+        ${TEST_DIR}/testkeys/key_rsa${keylen}.keyb
       let algorithmcounter=algorithmcounter+1
     done
   done
diff --git a/tests/testcases/test_file b/tests/testcases/test_file
new file mode 100644
index 0000000..3780a87
--- /dev/null
+++ b/tests/testcases/test_file
Binary files differ
diff --git a/tests/testcases/test_file.rsa1024_sha1.sig b/tests/testcases/test_file.rsa1024_sha1.sig
new file mode 100644
index 0000000..ab0f23f
--- /dev/null
+++ b/tests/testcases/test_file.rsa1024_sha1.sig
@@ -0,0 +1 @@
+&Á©ÕA»ÝEYDÐËÉ0>Ì`‘è}´»>Üø²ÛµÕA¨BÀý¤ñ1»‹ÏEôªdVš$t–ÜdFÒþ,ÅóہH5$5ŒÜÀő{ZÂèèúöŸW¦X·~S.ö+N:­aþqÁk&Š¤æÝG§8V'=¢Âˆh#[aUÙ·fß
\ No newline at end of file
diff --git a/tests/testcases/test_file.rsa1024_sha256.sig b/tests/testcases/test_file.rsa1024_sha256.sig
new file mode 100644
index 0000000..bfea38d
--- /dev/null
+++ b/tests/testcases/test_file.rsa1024_sha256.sig
Binary files differ
diff --git a/tests/testcases/test_file.rsa1024_sha512.sig b/tests/testcases/test_file.rsa1024_sha512.sig
new file mode 100644
index 0000000..ecd166a
--- /dev/null
+++ b/tests/testcases/test_file.rsa1024_sha512.sig
Binary files differ
diff --git a/tests/testcases/test_file.rsa2048_sha1.sig b/tests/testcases/test_file.rsa2048_sha1.sig
new file mode 100644
index 0000000..3c7c93f
--- /dev/null
+++ b/tests/testcases/test_file.rsa2048_sha1.sig
Binary files differ
diff --git a/tests/testcases/test_file.rsa2048_sha256.sig b/tests/testcases/test_file.rsa2048_sha256.sig
new file mode 100644
index 0000000..7a5362b
--- /dev/null
+++ b/tests/testcases/test_file.rsa2048_sha256.sig
@@ -0,0 +1 @@
+GO:s,©gG§Ö2æÃD‹ Í³¬ôtˆ~1ނÁ#½±j"ØPž5ßMźé¨Ðð„2÷‚	òÇ©$³Q¦F°!ˆ™8’»6º¦TӂFÍ"f{9¦õ³†âô†w ÑMB³­mÊ\|;œ'ú–'̑‡ _(3‰d†%9ó7œ._×êÔ{”ƒgÚÊ´4¼ H¢}å•‘6øú¡$Fz×ö\P<˜8`{¿t)îtû ¡âêÁ·vÓ[³æ¸¥\IÖ@4íGŸýCˆ‰a•€àz̵ãÕ9ëñ·ˆ‹ÚÒ®R«ŠÆåK]×9¡,‰ÇXy:5Tkic
\ No newline at end of file
diff --git a/tests/testcases/test_file.rsa2048_sha512.sig b/tests/testcases/test_file.rsa2048_sha512.sig
new file mode 100644
index 0000000..d047597
--- /dev/null
+++ b/tests/testcases/test_file.rsa2048_sha512.sig
Binary files differ
diff --git a/tests/testcases/test_file.rsa4096_sha1.sig b/tests/testcases/test_file.rsa4096_sha1.sig
new file mode 100644
index 0000000..cd3c2da
--- /dev/null
+++ b/tests/testcases/test_file.rsa4096_sha1.sig
Binary files differ
diff --git a/tests/testcases/test_file.rsa4096_sha256.sig b/tests/testcases/test_file.rsa4096_sha256.sig
new file mode 100644
index 0000000..140c564
--- /dev/null
+++ b/tests/testcases/test_file.rsa4096_sha256.sig
Binary files differ
diff --git a/tests/testcases/test_file.rsa4096_sha512.sig b/tests/testcases/test_file.rsa4096_sha512.sig
new file mode 100644
index 0000000..a088735
--- /dev/null
+++ b/tests/testcases/test_file.rsa4096_sha512.sig
Binary files differ
diff --git a/tests/testcases/test_file.rsa8192_sha1.sig b/tests/testcases/test_file.rsa8192_sha1.sig
new file mode 100644
index 0000000..4b704fa
--- /dev/null
+++ b/tests/testcases/test_file.rsa8192_sha1.sig
Binary files differ
diff --git a/tests/testcases/test_file.rsa8192_sha256.sig b/tests/testcases/test_file.rsa8192_sha256.sig
new file mode 100644
index 0000000..75ed86d
--- /dev/null
+++ b/tests/testcases/test_file.rsa8192_sha256.sig
Binary files differ
diff --git a/tests/testcases/test_file.rsa8192_sha512.sig b/tests/testcases/test_file.rsa8192_sha512.sig
new file mode 100644
index 0000000..49d002c
--- /dev/null
+++ b/tests/testcases/test_file.rsa8192_sha512.sig
Binary files differ
diff --git a/tests/testcases/test_file.sha1.digest b/tests/testcases/test_file.sha1.digest
new file mode 100644
index 0000000..96aabb0
--- /dev/null
+++ b/tests/testcases/test_file.sha1.digest
@@ -0,0 +1 @@
+ïk–‘¡f™«âĒÆ¢­d
\ No newline at end of file
diff --git a/tests/testcases/test_file.sha256.digest b/tests/testcases/test_file.sha256.digest
new file mode 100644
index 0000000..4e3497f
--- /dev/null
+++ b/tests/testcases/test_file.sha256.digest
@@ -0,0 +1 @@
+3e#<@lP…ÅàPÿ¾§ùðMÎ		ú	G"bØÀk
\ No newline at end of file
diff --git a/tests/testcases/test_file.sha512.digest b/tests/testcases/test_file.sha512.digest
new file mode 100644
index 0000000..b599d7d
--- /dev/null
+++ b/tests/testcases/test_file.sha512.digest
@@ -0,0 +1 @@
+2gÖô<º[Û.(ƒçXïBÎ@aiwažxk†‹&·j‚ëFµj9–%ìqÀ$¯¦¾lh	÷·p¢Ùr
\ No newline at end of file