/* Copyright (c) 2011 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 <stdint.h> #include <stdio.h> #define _STUB_IMPLEMENTATION_ #include "cryptolib.h" #include "file_keys.h" #include "rsa_padding_test.h" #include "test_common.h" #include "utility.h" #include "vboot_api.h" /* Data for mock functions */ static int mock_rsaverify_retval; /* Mock functions */ uint8_t* DigestBuf(const uint8_t* buf, uint64_t len, int sig_algorithm) { /* Just need to return something; it's only passed to the mock RSAVerify() */ return VbExMalloc(4); } int RSAVerify(const RSAPublicKey *key, const uint8_t* sig, const uint32_t sig_len, const uint8_t sig_type, const uint8_t* hash) { return mock_rsaverify_retval; } static void ResetMocks(void) { mock_rsaverify_retval = 1; } /* Test RSA utility funcs */ static void TestUtils(void) { RSAPublicKey* key; uint64_t u; /* Processed key size */ TEST_EQ(RSAProcessedKeySize(0, &u), 1, "Processed key size 0"); TEST_EQ(u, RSA1024NUMBYTES * 2 + sizeof(uint32_t) * 2, "Processed key size 0 size"); TEST_EQ(RSAProcessedKeySize(3, &u), 1, "Processed key size 3"); TEST_EQ(u, RSA2048NUMBYTES * 2 + sizeof(uint32_t) * 2, "Processed key size 3 size"); TEST_EQ(RSAProcessedKeySize(7, &u), 1, "Processed key size 7"); TEST_EQ(u, RSA4096NUMBYTES * 2 + sizeof(uint32_t) * 2, "Processed key size 7 size"); TEST_EQ(RSAProcessedKeySize(11, &u), 1, "Processed key size 11"); TEST_EQ(u, RSA8192NUMBYTES * 2 + sizeof(uint32_t) * 2, "Processed key size 11 size"); TEST_EQ(RSAProcessedKeySize(kNumAlgorithms, &u), 0, "Processed key size invalid algorithm"); /* Alloc key */ key = RSAPublicKeyNew(); TEST_EQ(key == NULL, 0, "New key not null"); /* New key fields */ TEST_PTR_EQ(key->n, NULL, "New key no n"); TEST_PTR_EQ(key->rr, NULL, "New key no rr"); TEST_EQ(key->len, 0, "New key len"); TEST_EQ(key->algorithm, kNumAlgorithms, "New key no algorithm"); /* Free key */ RSAPublicKeyFree(key); /* Freeing null key shouldn't implode */ RSAPublicKeyFree(NULL); } /* Test creating key from buffer */ static void TestKeyFromBuffer(void) { RSAPublicKey* key; uint8_t* buf; uint32_t* buf_key_len; int i; buf = malloc(8 + 2 * RSA8192NUMBYTES); buf_key_len = (uint32_t*)buf; for (i = 0; i < 4; i++) { uint32_t key_len = RSA1024NUMBYTES << i; Memset(buf, 0xAB, sizeof(buf)); *buf_key_len = key_len / sizeof(uint32_t); *(buf_key_len + 1) = 0xF00D2345; /* n0inv */ buf[8] = 100; buf[8 + key_len - 1] = 101; buf[8 + key_len] = 120; buf[8 + key_len * 2 - 1] = 121; /* Correct length */ key = RSAPublicKeyFromBuf(buf, 8 + key_len * 2); TEST_PTR_NEQ(key, NULL, "RSAPublicKeyFromBuf() ptr"); TEST_EQ(key->len, *buf_key_len, "RSAPublicKeyFromBuf() len"); TEST_EQ(key->n0inv, 0xF00D2345, "RSAPublicKeyFromBuf() n0inv"); TEST_PTR_NEQ(key->n, NULL, "RSAPublicKeyFromBuf() n ptr"); TEST_EQ(((uint8_t*)key->n)[0], 100, "RSAPublicKeyFromBuf() n start"); TEST_EQ(((uint8_t*)key->n)[key_len - 1], 101, "RSAPublicKeyFromBuf() n end"); TEST_PTR_NEQ(key->rr, NULL, "RSAPublicKeyFromBuf() rr ptr"); TEST_EQ(((uint8_t*)key->rr)[0], 120, "RSAPublicKeyFromBuf() rr start"); TEST_EQ(((uint8_t*)key->rr)[key_len - 1], 121, "RSAPublicKeyFromBuf() rr end"); RSAPublicKeyFree(key); /* Underflow and overflow */ TEST_PTR_EQ(RSAPublicKeyFromBuf(buf, 8 + key_len * 2 - 1), NULL, "RSAPublicKeyFromBuf() underflow"); TEST_PTR_EQ(RSAPublicKeyFromBuf(buf, 8 + key_len * 2 + 1), NULL, "RSAPublicKeyFromBuf() overflow"); /* Invalid key length in buffer */ *buf_key_len = key_len / sizeof(uint32_t) + 1; TEST_PTR_EQ(RSAPublicKeyFromBuf(buf, 8 + key_len * 2 + 1), NULL, "RSAPublicKeyFromBuf() invalid key length"); /* Valid key length in buffer, but for some other length key */ *buf_key_len = (RSA1024NUMBYTES << ((i + 1) & 3)) / sizeof(uint32_t); TEST_PTR_EQ(RSAPublicKeyFromBuf(buf, 8 + key_len * 2 + 1), NULL, "RSAPublicKeyFromBuf() key length for wrong key"); } free(buf); } /* Test verifying binary */ static void TestVerifyBinary(void) { RSAPublicKey key; uint8_t keybuf[8 + 2 * RSA1024NUMBYTES]; uint32_t* keybuf_len = (uint32_t*)keybuf; uint8_t buf[120]; uint8_t sig[4]; *keybuf_len = RSA1024NUMBYTES / sizeof(uint32_t); /* Successful verification */ ResetMocks(); TEST_EQ(RSAVerifyBinary_f(NULL, &key, buf, sizeof(buf), sig, 0), 1, "RSAVerifyBinary_f() success"); /* Successful verification using key blob */ TEST_EQ(RSAVerifyBinary_f(keybuf, NULL, buf, sizeof(buf), sig, 0), 1, "RSAVerifyBinary_f() success with keyblob"); /* Invalid algorithm */ ResetMocks(); TEST_EQ(RSAVerifyBinary_f(NULL, &key, buf, sizeof(buf), sig, kNumAlgorithms), 0, "RSAVerifyBinary_f() invalid algorithm"); /* Must have either a key or a key blob */ ResetMocks(); TEST_EQ(RSAVerifyBinary_f(NULL, NULL, buf, sizeof(buf), sig, kNumAlgorithms), 0, "RSAVerifyBinary_f() no key or key_blob"); /* Wrong algorithm for key buffer (so key buffer is wrong size) */ ResetMocks(); TEST_EQ(RSAVerifyBinary_f(keybuf, NULL, buf, sizeof(buf), sig, 3), 0, "RSAVerifyBinary_f() wrong alg for key blob"); /* Simulate failed verification */ ResetMocks(); mock_rsaverify_retval = 0; TEST_EQ(RSAVerifyBinary_f(NULL, &key, buf, sizeof(buf), sig, 0), 0, "RSAVerifyBinary_f() bad verify"); } /* Test verifying binary with digest */ static void TestVerifyBinaryWithDigest(void) { RSAPublicKey key; uint8_t keybuf[8 + 2 * RSA1024NUMBYTES]; uint32_t* keybuf_len = (uint32_t*)keybuf; uint8_t digest[120]; uint8_t sig[4]; *keybuf_len = RSA1024NUMBYTES / sizeof(uint32_t); /* Successful verification */ ResetMocks(); TEST_EQ(RSAVerifyBinaryWithDigest_f(NULL, &key, digest, sig, 0), 1, "RSAVerifyBinaryWithDigest_f() success"); /* Successful verification using key blob */ TEST_EQ(RSAVerifyBinaryWithDigest_f(keybuf, NULL, digest, sig, 0), 1, "RSAVerifyBinaryWithDigest_f() success with keyblob"); /* Invalid algorithm */ ResetMocks(); TEST_EQ(RSAVerifyBinaryWithDigest_f(NULL, &key, digest, sig, kNumAlgorithms), 0, "RSAVerifyBinaryWithDigest_f() invalid algorithm"); /* Must have either a key or a key blob */ ResetMocks(); TEST_EQ(RSAVerifyBinaryWithDigest_f(NULL, NULL, digest, sig, kNumAlgorithms), 0, "RSAVerifyBinaryWithDigest_f() no key or key_blob"); /* Wrong algorithm for key buffer (so key buffer is wrong size) */ ResetMocks(); TEST_EQ(RSAVerifyBinaryWithDigest_f(keybuf, NULL, digest, sig, 3), 0, "RSAVerifyBinaryWithDigest_f() wrong alg for key blob"); /* Simulate failed verification */ ResetMocks(); mock_rsaverify_retval = 0; TEST_EQ(RSAVerifyBinaryWithDigest_f(NULL, &key, digest, sig, 0), 0, "RSAVerifyBinaryWithDigest_f() bad verify"); } int main(int argc, char* argv[]) { int error_code = 0; /* Run tests */ TestUtils(); TestKeyFromBuffer(); TestVerifyBinary(); TestVerifyBinaryWithDigest(); if (!gTestSuccess) error_code = 255; return error_code; }