You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
220 lines
7.3 KiB
220 lines
7.3 KiB
/* 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;
|
|
}
|