diff options
author | Rob Austein <sra@hactrn.net> | 2016-09-01 19:03:05 -0400 |
---|---|---|
committer | Rob Austein <sra@hactrn.net> | 2016-09-01 19:03:05 -0400 |
commit | 65e8ef470b34a9c7af92f377da297095a0251890 (patch) | |
tree | 2e7213eb14424155fb6146e5f086052e5d756bf1 | |
parent | c2b116a5e46ed89bf1426def0c447d2e46cc9474 (diff) |
Move in-memory keystore from client to server. Whack with club until compiles.
Fixes for various minor issues found while integrating with sw/stm32.
Moving the in-memory keystore (PKCS #11 session objects, etc) from the
client library to the HSM was on the near term to-do list in any case,
doing it now turned out to be the easiest way to solve one of the
build problems.
-rw-r--r-- | Makefile | 47 | ||||
-rw-r--r-- | hal_internal.h | 12 | ||||
-rw-r--r-- | hash.c | 10 | ||||
-rw-r--r-- | ks.c | 4 | ||||
-rw-r--r-- | ks_flash.c | 30 | ||||
-rw-r--r-- | ks_mmap.c | 2 | ||||
-rw-r--r-- | ks_volatile.c | 4 | ||||
-rw-r--r-- | rpc_client.c | 139 | ||||
-rw-r--r-- | rpc_pkcs1.c | 82 | ||||
-rw-r--r-- | rpc_pkey.c | 64 | ||||
-rw-r--r-- | tests/test-rpc_pkey.c | 24 |
11 files changed, 179 insertions, 239 deletions
@@ -40,10 +40,10 @@ LIB = libhal.a # Error checking on known control options, some of which allow the user entirely too much rope. -USAGE := "usage: ${MAKE} [IO_BUS=eim|i2c|fmc] [RPC_MODE=none|server|client-simple|client-mixed] [KS=volatile|mmap|flash] [RPC_TRANSPORT=none|loopback|serial|daemon] [MODEXP_CORE=no|yes]" +USAGE := "usage: ${MAKE} [IO_BUS=eim|i2c|fmc] [RPC_MODE=none|server|client-simple|client-mixed] [KS=mmap|flash] [RPC_TRANSPORT=none|loopback|serial|daemon] [MODEXP_CORE=no|yes]" IO_BUS ?= none -KS ?= volatile +KS ?= flash RPC_MODE ?= none RPC_TRANSPORT ?= none MODEXP_CORE ?= no @@ -51,7 +51,7 @@ MODEXP_CORE ?= no ifeq (,$(and \ $(filter none eim i2c fmc ,${IO_BUS}),\ $(filter none server client-simple client-mixed ,${RPC_MODE}),\ - $(filter volatile mmap flash ,${KS}),\ + $(filter mmap flash ,${KS}),\ $(filter none loopback serial daemon ,${RPC_TRANSPORT}),\ $(filter no yes ,${MODEXP_CORE}))) $(error ${USAGE}) @@ -73,9 +73,8 @@ endif # makefile, so the working definition of "always want" is sometimes # just "building this is harmless even if we don't use it." -OBJ += errorstrings.o hash.o asn1.o ecdsa.o rsa.o ${KS_OBJ} xdr.o slip.o -OBJ += rpc_api.o rpc_hash.o rpc_misc.o rpc_pkey.o rpc_client.o rpc_server.o -OBJ += uuid.o +OBJ += errorstrings.o hash.o asn1.o ecdsa.o rsa.o xdr.o slip.o +OBJ += rpc_api.o rpc_hash.o uuid.o rpc_pkcs1.o # Object files to build when we're on a platform with direct access # to our hardware (Verilog) cores. @@ -106,20 +105,23 @@ ifneq "${IO_BUS}" "fmc" CFLAGS += -fPIC endif -# The mmap and flash keystore implementations are both server code. +# The keystore code has mutated a bit with the new API, and the Makefile, +# probably needs more extensive changes to track that. # -# The volatile keystore (conventional memory) is client code, to -# support using the same API for things like PKCS #11 "session" objects. +# In the old world, the volatile keystore was for the client side, +# while the flash and mmap keystores were for the server side (on the +# Alpha and the Novena, respectively). # -# Default at the moment is mmap, since that should work on the Novena -# and we haven't yet written the flash code for the bridge board. +# In the new world, all keystores are on the server side, and the +# volatile keystore is always present, to support things like PKCS #11 +# "session" objects. +# +# The mmap keystore hasn't been rewritten for the new API yet. -#KS_OBJ = ks.o +KS_OBJ = ks_volatile.o ifeq "${KS}" "mmap" KS_OBJ += ks_mmap.o -else ifeq "${KS}" "volatile" - KS_OBJ += ks_volatile.o else ifeq "${KS}" "flash" KS_OBJ += ks_flash.o masterkey.o endif @@ -145,18 +147,22 @@ ifneq "${RPC_MODE}" "server" OBJ += rpc_serial.o endif +RPC_CLIENT_OBJ = rpc_client.o + ifeq "${RPC_TRANSPORT}" "loopback" - RPC_CLIENT_OBJ = rpc_client_loopback.o + RPC_CLIENT_OBJ += rpc_client_loopback.o else ifeq "${RPC_TRANSPORT}" "serial" - RPC_CLIENT_OBJ = rpc_client_serial.o + RPC_CLIENT_OBJ += rpc_client_serial.o else ifeq "${RPC_TRANSPORT}" "daemon" - RPC_CLIENT_OBJ = rpc_client_daemon.o + RPC_CLIENT_OBJ += rpc_client_daemon.o endif +RPC_SERVER_OBJ = ${KS_OBJ} rpc_misc.o rpc_pkey.o rpc_server.o + ifeq "${RPC_TRANSPORT}" "loopback" - RPC_SERVER_OBJ = rpc_server_loopback.o + RPC_SERVER_OBJ += rpc_server_loopback.o else ifeq "${RPC_TRANSPORT}" "serial" - RPC_SERVER_OBJ = rpc_server_serial.o + RPC_SERVER_OBJ += rpc_server_serial.o endif ifeq "${RPC_MODE}" "none" @@ -171,7 +177,6 @@ else ifeq "${RPC_MODE}" "client-simple" else ifeq "${RPC_MODE}" "client-mixed" OBJ += ${RPC_CLIENT_OBJ} CFLAGS += -DRPC_CLIENT=RPC_CLIENT_MIXED -DHAL_RSA_USE_MODEXP=0 - KS = volatile endif ifndef CRYPTECH_ROOT @@ -234,7 +239,7 @@ asn1.o rsa.o ecdsa.o: asn1_internal.h ecdsa.o: ecdsa_curves.h novena-eim.o hal_io_eim.o: novena-eim.h slip.o rpc_client_serial.o rpc_server_serial.o: slip_internal.h -ks.o: last_gasp_pin_internal.h +ks_flash.o: last_gasp_pin_internal.h last_gasp_pin_internal.h: ./utils/last_gasp_default_pin >$@ diff --git a/hal_internal.h b/hal_internal.h index ff7381f..72f326c 100644 --- a/hal_internal.h +++ b/hal_internal.h @@ -250,9 +250,9 @@ extern const hal_rpc_pkey_dispatch_t hal_rpc_local_pkey_dispatch, hal_rpc_remote * and just pass the plain hash for everything else. */ -extern hal_error_t hal_rpc_pkey_pkcs1_construct_digestinfo(const hal_hash_handle_t handle, - uint8_t *digest_info, size_t *digest_info_len, - const size_t digest_info_max); +extern hal_error_t hal_rpc_pkcs1_construct_digestinfo(const hal_hash_handle_t handle, + uint8_t *digest_info, size_t *digest_info_len, + const size_t digest_info_max); /* * UUID stuff. All UUIDs we use (or are likely to use) are type 4 "random" UUIDs @@ -323,7 +323,7 @@ typedef struct { uint8_t salt[HAL_PIN_SALT_LENGTH]; } hal_ks_pin_t; -extern hal_error_t hal_ks_get_kek(uint8_t *kek, +extern hal_error_t hal_get_kek(uint8_t *kek, size_t *kek_len, const size_t kek_max); @@ -420,7 +420,9 @@ struct hal_ks { */ }; -extern const hal_ks_driver_t hal_ks_volatile_driver[1]; +extern const hal_ks_driver_t + hal_ks_volatile_driver[1], + hal_ks_token_driver[1]; static inline hal_error_t hal_ks_open(const hal_ks_driver_t * const driver, hal_ks_t **ks) @@ -969,15 +969,17 @@ static hal_error_t sw_hash_core_sha1(hal_hash_state_t *state) if (debug) fprintf(stderr, - "[Round %02d < a = 0x%08x, b = 0x%08x, c = 0x%08x, d = 0x%08x, e = 0x%08x, f = 0x%08x, k = 0x%08x, w = 0x%08x]\n", - i, S[a], S[b], S[c], S[d], S[e], f, k, W[i]); + "[Round %02d < a = 0x%08lx, b = 0x%08lx, c = 0x%08lx, d = 0x%08lx, e = 0x%08lx, f = 0x%08lx, k = 0x%08lx, w = 0x%08lx]\n", + i, (unsigned long) S[a], (unsigned long) S[b], (unsigned long) S[c], (unsigned long) S[d], (unsigned long) S[e], + (unsigned long) f, (unsigned long) k, (unsigned long) W[i]); S[e] = rot_l_32(S[a], 5) + f + S[e] + k + W[i]; S[b] = rot_l_32(S[b], 30); if (debug) - fprintf(stderr, "[Round %02d > a = 0x%08x, b = 0x%08x, c = 0x%08x, d = 0x%08x, e = 0x%08x]\n", - i, S[a], S[b], S[c], S[d], S[e]); + fprintf(stderr, "[Round %02d > a = 0x%08lx, b = 0x%08lx, c = 0x%08lx, d = 0x%08lx, e = 0x%08lx]\n", + i, (unsigned long) S[a], (unsigned long) S[b], + (unsigned long) S[c], (unsigned long) S[d], (unsigned long) S[e]); } for (int i = 0; i < 5; i++) @@ -117,7 +117,7 @@ hal_error_t hal_ks_store(const hal_key_type_t type, uint8_t kek[KEK_LENGTH]; size_t kek_len; - if ((err = hal_ks_get_kek(kek, &kek_len, sizeof(kek))) == HAL_OK) + if ((err = hal_get_kek(kek, &kek_len, sizeof(kek))) == HAL_OK) err = hal_aes_keywrap(NULL, kek, kek_len, der, der_len, k.der, &k.der_len); memset(kek, 0, sizeof(kek)); @@ -239,7 +239,7 @@ hal_error_t hal_ks_fetch(const hal_key_type_t type, *der_len = der_max; - if ((err = hal_ks_get_kek(kek, &kek_len, sizeof(kek))) == HAL_OK) + if ((err = hal_get_kek(kek, &kek_len, sizeof(kek))) == HAL_OK) err = hal_aes_keyunwrap(NULL, kek, kek_len, k->der, k->der_len, der, der_len); memset(kek, 0, sizeof(kek)); @@ -44,9 +44,13 @@ #undef HAL_OK #include <string.h> +#include <assert.h> +#include "last_gasp_pin_internal.h" -#define PAGE_SIZE_MASK (KEYSTORE_PAGE_SIZE - 1) +#define PAGE_SIZE_MASK (KEYSTORE_PAGE_SIZE - 1) + +#define KEK_LENGTH (bitsToBytes(256)) /* * Temporary hack: In-memory copy of entire (tiny) keystore database. @@ -98,7 +102,7 @@ static inline uint32_t _get_key_offset(uint32_t num) static hal_error_t ks_init(void) { - if (db.ks.driver == hal_ks_flash_driver) + if (db.ks.driver == hal_ks_token_driver) return LIBHAL_OK; if (db.ks.driver != NULL) @@ -107,7 +111,7 @@ static hal_error_t ks_init(void) uint8_t page_buf[KEYSTORE_PAGE_SIZE]; uint32_t idx = 0; /* Current index into db.keys[] */ - memset(db, 0, sizeof(*db)); + memset(&db, 0, sizeof(db)); if (keystore_check_id() != 1) return HAL_ERROR_KEYSTORE_ACCESS; @@ -184,7 +188,7 @@ static hal_error_t ks_init(void) idx++; } - db.ks.driver = hal_ks_flash_driver; + db.ks.driver = hal_ks_token_driver; return LIBHAL_OK; } @@ -208,7 +212,7 @@ static hal_error_t _write_data_to_flash(const uint32_t offset, const uint8_t *da return HAL_ERROR_KEYSTORE_ACCESS; } - return LIBLIBHAL_OK; + return LIBHAL_OK; } /* @@ -256,7 +260,7 @@ static hal_error_t ks_open(const hal_ks_driver_t * const driver, { hal_error_t err; - if (driver != hal_ks_flash_driver || ks == NULL) + if (driver != hal_ks_token_driver || ks == NULL) return HAL_ERROR_BAD_ARGUMENTS; if ((err = ks_init()) != LIBHAL_OK) @@ -328,7 +332,7 @@ static hal_error_t ks_fetch(hal_ks_t *ks, *der_len = der_max; - if ((err = hal_ks_get_kek(kek, &kek_len, sizeof(kek))) == LIBHAL_OK) + if ((err = hal_get_kek(kek, &kek_len, sizeof(kek))) == LIBHAL_OK) err = hal_aes_keyunwrap(NULL, kek, kek_len, k->der, k->der_len, der, der_len); memset(kek, 0, sizeof(kek)); @@ -401,7 +405,7 @@ static hal_error_t ks_store(hal_ks_t *ks, hal_error_t err; - if ((err = hal_ks_get_kek(kek, &kek_len, sizeof(kek))) == LIBHAL_OK) + if ((err = hal_get_kek(kek, &kek_len, sizeof(kek))) == LIBHAL_OK) err = hal_aes_keywrap(NULL, kek, kek_len, der, der_len, k.der, &k.der_len); memset(kek, 0, sizeof(kek)); @@ -483,7 +487,7 @@ static hal_error_t ks_delete(hal_ks_t *ks, if (k == NULL) return HAL_ERROR_KEY_NOT_FOUND; - const int loc = k - db.keys + const int loc = k - db.keys; uint32_t offset = _get_key_offset(loc); if (loc < 0 || offset > KEYSTORE_SECTOR_SIZE) @@ -500,9 +504,9 @@ static hal_error_t ks_delete(hal_ks_t *ks, return _write_data_to_flash(offset, (uint8_t *) k, sizeof(*k)); } -const hal_ks_driver_t hal_ks_flash_driver[1] = {{ - ks_flash_open, - ks_flash_close, +const hal_ks_driver_t hal_ks_token_driver[1] = {{ + ks_open, + ks_close, ks_store, ks_fetch, ks_delete, @@ -590,7 +594,7 @@ hal_error_t hal_ks_set_pin(const hal_user_t user, } -hal_error_t hal_ks_get_kek(uint8_t *kek, +hal_error_t hal_get_kek(uint8_t *kek, size_t *kek_len, const size_t kek_max) { @@ -144,7 +144,7 @@ hal_error_t hal_ks_set_pin(const hal_user_t user, return HAL_OK; } -hal_error_t hal_ks_get_kek(uint8_t *kek, +hal_error_t hal_get_kek(uint8_t *kek, size_t *kek_len, const size_t kek_max) { diff --git a/ks_volatile.c b/ks_volatile.c index 147e6c9..155ae04 100644 --- a/ks_volatile.c +++ b/ks_volatile.c @@ -157,7 +157,7 @@ static hal_error_t ks_store(hal_ks_t *ks, uint8_t kek[KEK_LENGTH]; size_t kek_len; - if ((err = hal_ks_get_kek(kek, &kek_len, sizeof(kek))) == HAL_OK) + if ((err = hal_get_kek(kek, &kek_len, sizeof(kek))) == HAL_OK) err = hal_aes_keywrap(NULL, kek, kek_len, der, der_len, k.der, &k.der_len); memset(kek, 0, sizeof(kek)); @@ -223,7 +223,7 @@ static hal_error_t ks_fetch(hal_ks_t *ks, *der_len = der_max; - if ((err = hal_ks_get_kek(kek, &kek_len, sizeof(kek))) == HAL_OK) + if ((err = hal_get_kek(kek, &kek_len, sizeof(kek))) == HAL_OK) err = hal_aes_keyunwrap(NULL, kek, kek_len, k->der, k->der_len, der, der_len); memset(kek, 0, sizeof(kek)); diff --git a/rpc_client.c b/rpc_client.c index 98d6abe..14ef23b 100644 --- a/rpc_client.c +++ b/rpc_client.c @@ -794,33 +794,14 @@ static hal_error_t pkey_remote_list(hal_pkey_info_t *result, } #if RPC_CLIENT == RPC_CLIENT_MIXED + /* * "Mixed" mode pkey operations, where the public key operation itself * takes place on the HSM but the hashing takes place locally. If * we're given a hash context in this case, it's local, so we have to * pull the digest from the hash context and send that to the HSM. - * - * These methods are also responsible for dispatching pkey operations - * to the local or remote key store based on the PROXIMATE flags. - * These flags are only meaningful when operating in mixed mode. */ -static inline const hal_rpc_pkey_dispatch_t *mixed_flags_dispatch(const hal_key_flags_t flags) -{ - if ((flags & HAL_KEY_FLAG_PROXIMATE) == 0) - return &hal_rpc_remote_pkey_dispatch; - else - return &hal_rpc_local_pkey_dispatch; -} - -static inline const hal_rpc_pkey_dispatch_t *mixed_handle_dispatch(const hal_pkey_handle_t pkey) -{ - if ((pkey.handle & HAL_PKEY_HANDLE_PROXIMATE_FLAG) == 0) - return &hal_rpc_remote_pkey_dispatch; - else - return &hal_rpc_local_pkey_dispatch; -} - static hal_error_t pkey_mixed_sign(const hal_session_handle_t session, const hal_pkey_handle_t pkey, const hal_hash_handle_t hash, @@ -828,7 +809,7 @@ static hal_error_t pkey_mixed_sign(const hal_session_handle_t session, uint8_t * signature, size_t *signature_len, const size_t signature_max) { if (input != NULL) - return mixed_handle_dispatch(pkey)->sign(session, pkey, hash, input, input_len, + return hal_rpc_remote_pkey_dispatch.sign(session, pkey, hash, input, input_len, signature, signature_len, signature_max); hal_digest_algorithm_t alg; @@ -847,7 +828,7 @@ static hal_error_t pkey_mixed_sign(const hal_session_handle_t session, case HAL_KEY_TYPE_RSA_PRIVATE: case HAL_KEY_TYPE_RSA_PUBLIC: - if ((err = hal_rpc_pkey_pkcs1_construct_digestinfo(hash, digest, &digest_len, sizeof(digest))) != HAL_OK) + if ((err = hal_rpc_pkcs1_construct_digestinfo(hash, digest, &digest_len, sizeof(digest))) != HAL_OK) return err; break; @@ -857,7 +838,7 @@ static hal_error_t pkey_mixed_sign(const hal_session_handle_t session, } - return mixed_handle_dispatch(pkey)->sign(session, pkey, hal_hash_handle_none, digest, digest_len, + return hal_rpc_remote_pkey_dispatch.sign(session, pkey, hal_hash_handle_none, digest, digest_len, signature, signature_len, signature_max); } @@ -868,7 +849,7 @@ static hal_error_t pkey_mixed_verify(const hal_session_handle_t session, const uint8_t * const signature, const size_t signature_len) { if (input != NULL) - return mixed_handle_dispatch(pkey)->verify(session, pkey, hash, input, input_len, + return hal_rpc_remote_pkey_dispatch.verify(session, pkey, hash, input, input_len, signature, signature_len); hal_digest_algorithm_t alg; @@ -887,7 +868,7 @@ static hal_error_t pkey_mixed_verify(const hal_session_handle_t session, case HAL_KEY_TYPE_RSA_PRIVATE: case HAL_KEY_TYPE_RSA_PUBLIC: - if ((err = hal_rpc_pkey_pkcs1_construct_digestinfo(hash, digest, &digest_len, sizeof(digest))) != HAL_OK) + if ((err = hal_rpc_pkcs1_construct_digestinfo(hash, digest, &digest_len, sizeof(digest))) != HAL_OK) return err; break; @@ -897,94 +878,10 @@ static hal_error_t pkey_mixed_verify(const hal_session_handle_t session, } - return mixed_handle_dispatch(pkey)->verify(session, pkey, hal_hash_handle_none, + return hal_rpc_remote_pkey_dispatch.verify(session, pkey, hal_hash_handle_none, digest, digest_len, signature, signature_len); } -static hal_error_t pkey_mixed_load(const hal_client_handle_t client, - const hal_session_handle_t session, - hal_pkey_handle_t *pkey, - const hal_key_type_t type, - const hal_curve_name_t curve, - hal_uuid_t *name, - const uint8_t * const der, const size_t der_len, - const hal_key_flags_t flags) -{ - return mixed_flags_dispatch(flags)->load(client, session, pkey, type, curve, name, der, der_len, flags); -} - -static hal_error_t pkey_mixed_find(const hal_client_handle_t client, - const hal_session_handle_t session, - hal_pkey_handle_t *pkey, - const hal_key_type_t type, - const hal_uuid_t * const name, - const hal_key_flags_t flags) -{ - return mixed_flags_dispatch(flags)->find(client, session, pkey, type, name, flags); -} - -static hal_error_t pkey_mixed_generate_rsa(const hal_client_handle_t client, - const hal_session_handle_t session, - hal_pkey_handle_t *pkey, - hal_uuid_t *name, - const unsigned key_length, - const uint8_t * const public_exponent, const size_t public_exponent_len, - const hal_key_flags_t flags) -{ - return mixed_flags_dispatch(flags)->generate_rsa(client, session, pkey, name, key_length, - public_exponent, public_exponent_len, flags); -} - -static hal_error_t pkey_mixed_generate_ec(const hal_client_handle_t client, - const hal_session_handle_t session, - hal_pkey_handle_t *pkey, - hal_uuid_t *name, - const hal_curve_name_t curve, - const hal_key_flags_t flags) -{ - return mixed_flags_dispatch(flags)->generate_ec(client, session, pkey, name, curve, flags); -} - -static hal_error_t pkey_mixed_close(const hal_pkey_handle_t pkey) -{ - return mixed_handle_dispatch(pkey)->close(pkey); -} - -static hal_error_t pkey_mixed_delete(const hal_pkey_handle_t pkey) -{ - return mixed_handle_dispatch(pkey)->delete(pkey); -} - -static hal_error_t pkey_mixed_get_key_type(const hal_pkey_handle_t pkey, - hal_key_type_t *key_type) -{ - return mixed_handle_dispatch(pkey)->get_key_type(pkey, key_type); -} - -static hal_error_t pkey_mixed_get_key_flags(const hal_pkey_handle_t pkey, - hal_key_flags_t *flags) -{ - return mixed_handle_dispatch(pkey)->get_key_flags(pkey, flags); -} - -static size_t pkey_mixed_get_public_key_len(const hal_pkey_handle_t pkey) -{ - return mixed_handle_dispatch(pkey)->get_public_key_len(pkey); -} - -static hal_error_t pkey_mixed_get_public_key(const hal_pkey_handle_t pkey, - uint8_t *der, size_t *der_len, const size_t der_max) -{ - return mixed_handle_dispatch(pkey)->get_public_key(pkey, der, der_len, der_max); -} - -static hal_error_t pkey_mixed_list(hal_pkey_info_t *result, - unsigned *result_len, - const unsigned result_max, - hal_key_flags_t flags) -{ - return mixed_flags_dispatch(flags)->list(result, result_len, result_max, flags); -} #endif /* RPC_CLIENT == RPC_CLIENT_MIXED */ /* @@ -1028,19 +925,19 @@ const hal_rpc_pkey_dispatch_t hal_rpc_remote_pkey_dispatch = { #if RPC_CLIENT == RPC_CLIENT_MIXED const hal_rpc_pkey_dispatch_t hal_rpc_mixed_pkey_dispatch = { - pkey_mixed_load, - pkey_mixed_find, - pkey_mixed_generate_rsa, - pkey_mixed_generate_ec, - pkey_mixed_close, - pkey_mixed_delete, - pkey_mixed_get_key_type, - pkey_mixed_get_key_flags, - pkey_mixed_get_public_key_len, - pkey_mixed_get_public_key, + pkey_remote_load, + pkey_remote_find, + pkey_remote_generate_rsa, + pkey_remote_generate_ec, + pkey_remote_close, + pkey_remote_delete, + pkey_remote_get_key_type, + pkey_remote_get_key_flags, + pkey_remote_get_public_key_len, + pkey_remote_get_public_key, pkey_mixed_sign, pkey_mixed_verify, - pkey_mixed_list + pkey_remote_list }; #endif /* RPC_CLIENT == RPC_CLIENT_MIXED */ diff --git a/rpc_pkcs1.c b/rpc_pkcs1.c new file mode 100644 index 0000000..2dcf9dd --- /dev/null +++ b/rpc_pkcs1.c @@ -0,0 +1,82 @@ +/* + * rpc_pkcs1.c + * ----------- + * PKCS #1 (RSA) support code layered on top of RPC hash API. + * + * Copyright (c) 2016, NORDUnet A/S All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of the NORDUnet nor the names of its contributors may + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> + +#include "hal.h" +#include "hal_internal.h" + +/* + * Construct a PKCS #1 DigestInfo object. This requires some (very + * basic) ASN.1 encoding, which we perform inline. + */ + +hal_error_t hal_rpc_pkcs1_construct_digestinfo(const hal_hash_handle_t handle, + uint8_t *digest_info, size_t *digest_info_len, + const size_t digest_info_max) +{ + assert(digest_info != NULL && digest_info_len != NULL); + + hal_digest_algorithm_t alg; + size_t len, alg_len; + hal_error_t err; + + if ((err = hal_rpc_hash_get_algorithm(handle, &alg)) != HAL_OK || + (err = hal_rpc_hash_get_digest_length(alg, &len)) != HAL_OK || + (err = hal_rpc_hash_get_digest_algorithm_id(alg, NULL, &alg_len, 0)) != HAL_OK) + return err; + + *digest_info_len = len + alg_len + 4; + + if (*digest_info_len >= digest_info_max) + return HAL_ERROR_RESULT_TOO_LONG; + + assert(*digest_info_len < 130); + + uint8_t *d = digest_info; + + *d++ = 0x30; /* SEQUENCE */ + *d++ = (uint8_t) (*digest_info_len - 2); + + if ((err = hal_rpc_hash_get_digest_algorithm_id(alg, d, NULL, alg_len)) != HAL_OK) + return err; + d += alg_len; + + *d++ = 0x04; /* OCTET STRING */ + *d++ = (uint8_t) len; + + assert(digest_info + *digest_info_len == d + len); + + return hal_rpc_hash_finalize(handle, d, len); +} @@ -113,49 +113,6 @@ static inline hal_pkey_slot_t *find_handle(const hal_pkey_handle_t handle) */ /* - * Construct a PKCS #1 DigestInfo object. This requires some (very - * basic) ASN.1 encoding, which we perform inline. - */ - -hal_error_t hal_rpc_pkey_pkcs1_construct_digestinfo(const hal_hash_handle_t handle, - uint8_t *digest_info, size_t *digest_info_len, const size_t digest_info_max) -{ - assert(digest_info != NULL && digest_info_len != NULL); - - hal_digest_algorithm_t alg; - size_t len, alg_len; - hal_error_t err; - - if ((err = hal_rpc_hash_get_algorithm(handle, &alg)) != HAL_OK || - (err = hal_rpc_hash_get_digest_length(alg, &len)) != HAL_OK || - (err = hal_rpc_hash_get_digest_algorithm_id(alg, NULL, &alg_len, 0)) != HAL_OK) - return err; - - *digest_info_len = len + alg_len + 4; - - if (*digest_info_len >= digest_info_max) - return HAL_ERROR_RESULT_TOO_LONG; - - assert(*digest_info_len < 130); - - uint8_t *d = digest_info; - - *d++ = 0x30; /* SEQUENCE */ - *d++ = (uint8_t) (*digest_info_len - 2); - - if ((err = hal_rpc_hash_get_digest_algorithm_id(alg, d, NULL, alg_len)) != HAL_OK) - return err; - d += alg_len; - - *d++ = 0x04; /* OCTET STRING */ - *d++ = (uint8_t) len; - - assert(digest_info + *digest_info_len == d + len); - - return hal_rpc_hash_finalize(handle, d, len); -} - -/* * Pad an octet string with PKCS #1.5 padding for use with RSA. * * For the moment, this only handles type 01 encryption blocks, thus @@ -203,19 +160,10 @@ static hal_error_t pkcs1_5_pad(const uint8_t * const data, const size_t data_len static inline hal_error_t ks_open_from_flags(hal_ks_t **ks, const hal_key_flags_t flags) { - if ((flags & HAL_KEY_FLAG_TOKEN) == 0) - return hal_ks_open(hal_ks_volatile_driver, ks); - -#if 0 - - return hal_ks_open(hal_ks_token_driver, ks); - -#else -#warning This needs to open hal_ks_token_driver here, once we get around to writing that driver - - return HAL_ERROR_KS_DRIVER_NOT_FOUND; - -#endif + return hal_ks_open((flags & HAL_KEY_FLAG_TOKEN) == 0 + ? hal_ks_volatile_driver + : hal_ks_token_driver, + ks); } /* @@ -640,7 +588,7 @@ static hal_error_t pkey_local_sign_rsa(uint8_t *keybuf, const size_t keybuf_len, return HAL_ERROR_RESULT_TOO_LONG; if (input == NULL) { - if ((err = hal_rpc_pkey_pkcs1_construct_digestinfo(hash, signature, &input_len, *signature_len)) != HAL_OK) + if ((err = hal_rpc_pkcs1_construct_digestinfo(hash, signature, &input_len, *signature_len)) != HAL_OK) return err; input = signature; } @@ -773,7 +721,7 @@ static hal_error_t pkey_local_verify_rsa(uint8_t *keybuf, const size_t keybuf_le return err; if (input == NULL) { - if ((err = hal_rpc_pkey_pkcs1_construct_digestinfo(hash, expected, &input_len, sizeof(expected))) != HAL_OK) + if ((err = hal_rpc_pkcs1_construct_digestinfo(hash, expected, &input_len, sizeof(expected))) != HAL_OK) return err; input = expected; } diff --git a/tests/test-rpc_pkey.c b/tests/test-rpc_pkey.c index f6b6f15..61523b8 100644 --- a/tests/test-rpc_pkey.c +++ b/tests/test-rpc_pkey.c @@ -81,7 +81,7 @@ static int test_rsa_testvec(const rsa_tc_t * const tc) tc->dQ.val, tc->dQ.len)) != HAL_OK) return printf("Could not load RSA private key from test vector: %s\n", hal_error_string(err)), 0; - const uint8_t private_label[] = "RSA private key", public_label[] = "RSA public key"; + hal_uuid_t private_name, public_name; uint8_t private_der[hal_rsa_private_key_to_der_len(tc_key)]; uint8_t public_der[hal_rsa_public_key_to_der_len(tc_key)]; @@ -92,7 +92,7 @@ static int test_rsa_testvec(const rsa_tc_t * const tc) assert(len == sizeof(private_der)); if ((err = hal_rpc_pkey_load(client, session, &private_key, HAL_KEY_TYPE_RSA_PRIVATE, HAL_CURVE_NONE, - private_label, sizeof(private_label), private_der, sizeof(private_der), + &private_name, private_der, sizeof(private_der), HAL_KEY_FLAG_USAGE_DIGITALSIGNATURE)) != HAL_OK) return printf("Could not load private key into RPC: %s\n", hal_error_string(err)), 0; @@ -102,7 +102,7 @@ static int test_rsa_testvec(const rsa_tc_t * const tc) assert(len == sizeof(public_der)); if ((err = hal_rpc_pkey_load(client, session, &public_key, HAL_KEY_TYPE_RSA_PUBLIC, HAL_CURVE_NONE, - public_label, sizeof(public_label), public_der, sizeof(public_der), + &public_name, public_der, sizeof(public_der), HAL_KEY_FLAG_USAGE_DIGITALSIGNATURE)) != HAL_OK) return printf("Could not load public key into RPC: %s\n", hal_error_string(err)), 0; @@ -157,7 +157,7 @@ static int test_ecdsa_testvec(const ecdsa_tc_t * const tc) tc->d, tc->d_len)) != HAL_OK) return printf("Could not load ECDSA private key from test vector: %s\n", hal_error_string(err)), 0; - const uint8_t private_label[] = "ECDSA private key", public_label[] = "ECDSA public key"; + hal_uuid_t private_name, public_name; uint8_t private_der[hal_ecdsa_private_key_to_der_len(tc_key)]; uint8_t public_der[hal_ecdsa_public_key_to_der_len(tc_key)]; @@ -168,7 +168,7 @@ static int test_ecdsa_testvec(const ecdsa_tc_t * const tc) assert(len == sizeof(private_der)); if ((err = hal_rpc_pkey_load(client, session, &private_key, HAL_KEY_TYPE_EC_PRIVATE, tc->curve, - private_label, sizeof(private_label), private_der, sizeof(private_der), + &private_name, private_der, sizeof(private_der), HAL_KEY_FLAG_USAGE_DIGITALSIGNATURE)) != HAL_OK) return printf("Could not load private key into RPC: %s\n", hal_error_string(err)), 0; @@ -178,7 +178,7 @@ static int test_ecdsa_testvec(const ecdsa_tc_t * const tc) assert(len == sizeof(public_der)); if ((err = hal_rpc_pkey_load(client, session, &public_key, HAL_KEY_TYPE_EC_PUBLIC, tc->curve, - public_label, sizeof(public_label), public_der, sizeof(public_der), + &public_name, public_der, sizeof(public_der), HAL_KEY_FLAG_USAGE_DIGITALSIGNATURE)) != HAL_OK) return printf("Could not load public key into RPC: %s\n", hal_error_string(err)), 0; @@ -218,9 +218,9 @@ static int test_rsa_generate(const rsa_tc_t * const tc) printf("Starting %lu-bit RSA key generation tests\n", (unsigned long) tc->size); - const uint8_t private_label[] = "Generated RSA private key", public_label[] = "Generated RSA public key"; + hal_uuid_t private_name, public_name; - if ((err = hal_rpc_pkey_generate_rsa(client, session, &private_key, private_label, sizeof(private_label), + if ((err = hal_rpc_pkey_generate_rsa(client, session, &private_key, &private_name, tc->size, tc->e.val, tc->e.len, HAL_KEY_FLAG_USAGE_DIGITALSIGNATURE)) != HAL_OK) return printf("Could not generate RSA private key: %s\n", hal_error_string(err)), 0; @@ -233,7 +233,7 @@ static int test_rsa_generate(const rsa_tc_t * const tc) assert(len == sizeof(public_der)); if ((err = hal_rpc_pkey_load(client, session, &public_key, HAL_KEY_TYPE_RSA_PUBLIC, HAL_CURVE_NONE, - public_label, sizeof(public_label), public_der, sizeof(public_der), + &public_name, public_der, sizeof(public_der), HAL_KEY_FLAG_USAGE_DIGITALSIGNATURE)) != HAL_OK) return printf("Could not load public key into RPC: %s\n", hal_error_string(err)), 0; @@ -277,10 +277,10 @@ static int test_ecdsa_generate(const ecdsa_tc_t * const tc) printf("Starting ECDSA %s key generation tests\n", ecdsa_curve_to_string(tc->curve)); - const uint8_t private_label[] = "Generated ECDSA private key", public_label[] = "Generated ECDSA public key"; + hal_uuid_t private_name, public_name; if ((err = hal_rpc_pkey_generate_ec(client, session, &private_key, - private_label, sizeof(private_label), + &private_name, tc->curve, HAL_KEY_FLAG_USAGE_DIGITALSIGNATURE)) != HAL_OK) return printf("Could not generate EC key pair: %s\n", hal_error_string(err)), 0; @@ -292,7 +292,7 @@ static int test_ecdsa_generate(const ecdsa_tc_t * const tc) assert(len == sizeof(public_der)); if ((err = hal_rpc_pkey_load(client, session, &public_key, HAL_KEY_TYPE_EC_PUBLIC, tc->curve, - public_label, sizeof(public_label), public_der, sizeof(public_der), + &public_name, public_der, sizeof(public_der), HAL_KEY_FLAG_USAGE_DIGITALSIGNATURE)) != HAL_OK) return printf("Could not load public key into RPC: %s\n", hal_error_string(err)), 0; |