From 13326d8cf8d8e6f56af5b8d1b9afcaeadfbdd315 Mon Sep 17 00:00:00 2001 From: Laurence Lundblade Date: Mon, 2 May 2022 18:33:17 -0600 Subject: [PATCH 01/11] Prelim version at austere sign (it works) --- Makefile.ossl | 4 +- inc/t_cose/t_cose_austere_sign.h | 30 +++++++ inc/t_cose_austere_sign.h | 13 +++ src/t_cose_austere_sign.c | 135 +++++++++++++++++++++++++++++++ t_cose.xcodeproj/project.pbxproj | 20 +++++ test/run_tests.c | 2 + test/t_cose_austere_test.c | 63 +++++++++++++++ test/t_cose_austere_test.h | 17 ++++ 8 files changed, 282 insertions(+), 2 deletions(-) create mode 100644 inc/t_cose/t_cose_austere_sign.h create mode 100644 inc/t_cose_austere_sign.h create mode 100644 src/t_cose_austere_sign.c create mode 100644 test/t_cose_austere_test.c create mode 100644 test/t_cose_austere_test.h diff --git a/Makefile.ossl b/Makefile.ossl index 572f031c..9e6e6590 100644 --- a/Makefile.ossl +++ b/Makefile.ossl @@ -54,7 +54,7 @@ C_OPTS=-Os -fPIC # ---- T_COSE Config and test options ---- TEST_CONFIG_OPTS= -TEST_OBJ=test/t_cose_test.o test/run_tests.o test/t_cose_sign_verify_test.o test/t_cose_make_test_messages.o $(CRYPTO_TEST_OBJ) +TEST_OBJ=test/t_cose_test.o test/run_tests.o test/t_cose_sign_verify_test.o test/t_cose_make_test_messages.o test/t_cose_austere_test.o $(CRYPTO_TEST_OBJ) # ---- the main body that is invariant ---- @@ -62,7 +62,7 @@ INC=-I inc -I test -I src ALL_INC=$(INC) $(CRYPTO_INC) $(QCBOR_INC) CFLAGS=$(CMD_LINE) $(ALL_INC) $(C_OPTS) $(TEST_CONFIG_OPTS) $(CRYPTO_CONFIG_OPTS) -SRC_OBJ=src/t_cose_sign1_verify.o src/t_cose_sign1_sign.o src/t_cose_util.o src/t_cose_parameters.o +SRC_OBJ=src/t_cose_sign1_verify.o src/t_cose_sign1_sign.o src/t_cose_austere_sign.o src/t_cose_util.o src/t_cose_parameters.o .PHONY: all install install_headers install_so uninstall clean diff --git a/inc/t_cose/t_cose_austere_sign.h b/inc/t_cose/t_cose_austere_sign.h new file mode 100644 index 00000000..19f9862f --- /dev/null +++ b/inc/t_cose/t_cose_austere_sign.h @@ -0,0 +1,30 @@ +// +// t_cose_austere_sign.h +// t_cose +// +// Created by Laurence Lundblade on 5/2/22. +// Copyright © 2022 Laurence Lundblade. All rights reserved. +// + +#ifndef t_cose_austere_sign_h +#define t_cose_austere_sign_h + + +#include "t_cose/q_useful_buf.h" +#include "t_cose/t_cose_common.h" + +/* The algorithm ID, and such are defined as hard constants + * in the implementation. + * The payload length is also defined in the implementation + * despite being passed in here in payload.len + * + * + */ +enum t_cose_err_t +t_cose_austere_sign(struct q_useful_buf_c payload, + struct t_cose_key signing_key, + struct q_useful_buf output_buffer, + struct q_useful_buf_c *output); + + +#endif /* t_cose_austere_sign_h */ diff --git a/inc/t_cose_austere_sign.h b/inc/t_cose_austere_sign.h new file mode 100644 index 00000000..8a61b37f --- /dev/null +++ b/inc/t_cose_austere_sign.h @@ -0,0 +1,13 @@ +// +// t_cose_austere_sign.h +// t_cose +// +// Created by Laurence Lundblade on 5/2/22. +// Copyright © 2022 Laurence Lundblade. All rights reserved. +// + +#ifndef t_cose_austere_sign_h +#define t_cose_austere_sign_h + + +#endif /* t_cose_austere_sign_h */ diff --git a/src/t_cose_austere_sign.c b/src/t_cose_austere_sign.c new file mode 100644 index 00000000..e492274f --- /dev/null +++ b/src/t_cose_austere_sign.c @@ -0,0 +1,135 @@ +// +// t_cose_austere_sign.c +// t_cose +// +// Created by Laurence Lundblade on 5/2/22. +// Copyright © 2022 Laurence Lundblade. All rights reserved. +// + +#include "t_cose/t_cose_austere_sign.h" +#include "t_cose/t_cose_common.h" + +/* + 1) start the hash function + + 2) hash the fixed byte string that is start of the Sig_structure + + 3) hash the payload + + 4) finish the hash + + 5) copy the COSE_Sign1 stuff before the payload to the output. + + 6) copy the payload to the output + + 7) copy another fixed length string to the output, the bstr head for the signature + + 7) call ECDA sign with the hash as input and output directly to the output buffer + */ + + +#include "t_cose_crypto.h" + +// Adjust these for algorithm and payload length +#define PAYLOAD_LEN 128 // Only works for lengths > 24 and < 256 +#define COSE_HASH COSE_ALGORITHM_SHA_384 +#define ENCODED_EC384 0x22 // Make sure this is the right encoding if you change this +#define ENCODED_EC384_SIG_LEN 96 // Make sure this is the right encoding if you change this + + +/* This has all sort of stuff packed in and hard coded, including the payload length. + + * Sig_structure = [ + * context : "Signature" / "Signature1" / "CounterSignature", + * body_protected : empty_or_serialized_map, + * ? sign_protected : empty_or_serialized_map, + * external_aad : bstr, + * payload : bstr + * ] + + */ + +static uint8_t start_sig_struct[] = { + 0x84, + 0x6A, + 'S', 'i', 'g', 'n', 'a', 't', 'u', 'r', 'e', '1', + 0x44, 0xA1, 0x01, 0x38, ENCODED_EC384, // bstr wrapped protected header wtih algorithm ID + 0x40, // Empty bstr for aad + 0x58, PAYLOAD_LEN, +}; + +static uint8_t start_cose_sign1[] = { + 0x84, + 0x44, 0xA1, 0x01, 0x38, ENCODED_EC384, // bstr wrapped protected header wtih algorithm ID + 0xa0, // no unprotected headers, put some here if you want + 0x58, PAYLOAD_LEN, +}; + +static uint8_t cose_sign1_sig_start[] = { + 0x58, 96 +}; + + + +enum t_cose_err_t +t_cose_austere_sign(const struct q_useful_buf_c payload, + struct t_cose_key signing_key, + const struct q_useful_buf output_buffer, + struct q_useful_buf_c *output) +{ + + struct t_cose_crypto_hash hash_ctx; + enum t_cose_err_t err; + struct q_useful_buf_c computed_hash; + struct q_useful_buf_c signature; + size_t cose_sign1_len; + + + MakeUsefulBufOnStack(hash_output, 64); // TODO: correct size for selected hash + + /* --- hash the Sig_structure --- */ + err = t_cose_crypto_hash_start(&hash_ctx, COSE_ALGORITHM_SHA_384); + + t_cose_crypto_hash_update(&hash_ctx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(start_sig_struct)); + t_cose_crypto_hash_update(&hash_ctx, payload); + + err = t_cose_crypto_hash_finish(&hash_ctx, hash_output, &computed_hash); + + + /* --- Copy first part of COSE_Sign1 to output buffer -- */ + cose_sign1_len = 0; + + const struct q_useful_buf_c xx = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(start_cose_sign1); + q_useful_buf_copy(output_buffer, xx); + + cose_sign1_len += xx.len; + + /* -- Copy the payload to the output buffer -- */ + useful_buf_copy_offset(output_buffer, cose_sign1_len, payload); + + cose_sign1_len += payload.len; + + /* -- Do the signing and put it in the output buffer */ + const struct q_useful_buf_c yy = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(cose_sign1_sig_start); + + useful_buf_copy_offset(output_buffer, cose_sign1_len, yy); + + cose_sign1_len += yy.len; + + struct q_useful_buf tmp = {(uint8_t *)output_buffer.ptr + cose_sign1_len, + output_buffer.len - cose_sign1_len}; + + + t_cose_crypto_sign(T_COSE_ALGORITHM_ES384, + signing_key, + computed_hash, + tmp, + &signature); + + cose_sign1_len += signature.len; + + output->ptr = output_buffer.ptr; + output->len = cose_sign1_len; + + return 0; +} diff --git a/t_cose.xcodeproj/project.pbxproj b/t_cose.xcodeproj/project.pbxproj index c57154e9..ae32e5b9 100644 --- a/t_cose.xcodeproj/project.pbxproj +++ b/t_cose.xcodeproj/project.pbxproj @@ -60,6 +60,12 @@ E772027C23CAEC84006E966E /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = E7E36E7B226CB8400040613B /* main.c */; }; E772027D23CAEC84006E966E /* run_tests.c in Sources */ = {isa = PBXBuildFile; fileRef = E72FB01C231ADAA8000970FE /* run_tests.c */; }; E772027E23CAEC84006E966E /* t_cose_sign1_sign.c in Sources */ = {isa = PBXBuildFile; fileRef = E7E36E8E226CB9460040613B /* t_cose_sign1_sign.c */; }; + E774835B28209B3200B352ED /* t_cose_austere_sign.c in Sources */ = {isa = PBXBuildFile; fileRef = E774835A28209B3200B352ED /* t_cose_austere_sign.c */; }; + E774835C28209B3200B352ED /* t_cose_austere_sign.c in Sources */ = {isa = PBXBuildFile; fileRef = E774835A28209B3200B352ED /* t_cose_austere_sign.c */; }; + E774835D28209B3200B352ED /* t_cose_austere_sign.c in Sources */ = {isa = PBXBuildFile; fileRef = E774835A28209B3200B352ED /* t_cose_austere_sign.c */; }; + E77483612820A94B00B352ED /* t_cose_austere_test.c in Sources */ = {isa = PBXBuildFile; fileRef = E77483602820A94B00B352ED /* t_cose_austere_test.c */; }; + E77483622820A94B00B352ED /* t_cose_austere_test.c in Sources */ = {isa = PBXBuildFile; fileRef = E77483602820A94B00B352ED /* t_cose_austere_test.c */; }; + E77483632820A94B00B352ED /* t_cose_austere_test.c in Sources */ = {isa = PBXBuildFile; fileRef = E77483602820A94B00B352ED /* t_cose_austere_test.c */; }; E7C960A627F7569E00FB537C /* libqcbor.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E7C960A527F7569500FB537C /* libqcbor.a */; }; E7C960A727F7569F00FB537C /* libqcbor.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E7C960A527F7569500FB537C /* libqcbor.a */; }; E7C960A827F756A000FB537C /* libqcbor.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E7C960A527F7569500FB537C /* libqcbor.a */; }; @@ -187,6 +193,10 @@ E751F9EE27E1F85000EBA5FA /* crypto_values.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = crypto_values.h; path = ../../../../../usr/local/include/psa/crypto_values.h; sourceTree = ""; }; E751F9F027E1F90F00EBA5FA /* libmbedcrypto.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmbedcrypto.a; path = ../../../../../usr/local/lib/libmbedcrypto.a; sourceTree = ""; }; E772028523CAEC84006E966E /* t_cose_psa_noss */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = t_cose_psa_noss; sourceTree = BUILT_PRODUCTS_DIR; }; + E774835A28209B3200B352ED /* t_cose_austere_sign.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = t_cose_austere_sign.c; sourceTree = ""; }; + E774835E28209BC500B352ED /* t_cose_austere_sign.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = t_cose_austere_sign.h; path = t_cose/t_cose_austere_sign.h; sourceTree = ""; }; + E774835F2820A94B00B352ED /* t_cose_austere_test.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = t_cose_austere_test.h; sourceTree = ""; }; + E77483602820A94B00B352ED /* t_cose_austere_test.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = t_cose_austere_test.c; sourceTree = ""; }; E7C960A527F7569500FB537C /* libqcbor.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libqcbor.a; path = ../../../../../usr/local/lib/libqcbor.a; sourceTree = ""; }; E7E36E78226CB8400040613B /* t_cose_openssl */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = t_cose_openssl; sourceTree = BUILT_PRODUCTS_DIR; }; E7E36E7B226CB8400040613B /* main.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = main.c; sourceTree = ""; }; @@ -336,6 +346,7 @@ E7E36E82226CB9460040613B /* inc */ = { isa = PBXGroup; children = ( + E774835E28209BC500B352ED /* t_cose_austere_sign.h */, E72EC9EF242E74EE006D3DD3 /* q_useful_buf.h */, E72EC9ED242E74EE006D3DD3 /* t_cose_common.h */, E72EC9EC242E74EE006D3DD3 /* t_cose_sign1_sign.h */, @@ -355,6 +366,7 @@ E7E36E8C226CB9460040613B /* t_cose_util.h */, E7E36E8D226CB9460040613B /* t_cose_crypto.h */, E7E36E8E226CB9460040613B /* t_cose_sign1_sign.c */, + E774835A28209B3200B352ED /* t_cose_austere_sign.c */, ); path = src; sourceTree = ""; @@ -403,6 +415,8 @@ E721CB9723628E0B00C7FD56 /* t_cose_make_test_pub_key.h */, E721CB9823628E9E00C7FD56 /* t_cose_make_openssl_test_key.c */, E721CB9123628B5F00C7FD56 /* t_cose_make_psa_test_key.c */, + E774835F2820A94B00B352ED /* t_cose_austere_test.h */, + E77483602820A94B00B352ED /* t_cose_austere_test.c */, ); path = test; sourceTree = ""; @@ -561,8 +575,10 @@ E730E61223612DAB00175CE0 /* t_cose_make_test_messages.c in Sources */, E730E61323612DAB00175CE0 /* t_cose_util.c in Sources */, E730E61523612DAB00175CE0 /* sha256.c in Sources */, + E774835B28209B3200B352ED /* t_cose_austere_sign.c in Sources */, E730E61623612DAB00175CE0 /* t_cose_test.c in Sources */, E730E61823612DAB00175CE0 /* main.c in Sources */, + E77483612820A94B00B352ED /* t_cose_austere_test.c in Sources */, E730E61923612DAB00175CE0 /* t_cose_sign1_sign.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -600,6 +616,7 @@ files = ( E73CDAAE23A7316700D262E0 /* t_cose_sign1_verify.c in Sources */, E73CDAB023A7316700D262E0 /* t_cose_test.c in Sources */, + E774835D28209B3200B352ED /* t_cose_austere_sign.c in Sources */, E73CDAD423AD4F3900D262E0 /* t_cose_psa_crypto.c in Sources */, E73CDAB223A7316700D262E0 /* t_cose_util.c in Sources */, E73CDAB623A7316700D262E0 /* t_cose_parameters.c in Sources */, @@ -609,6 +626,7 @@ E73CDABC23A7316700D262E0 /* t_cose_make_test_messages.c in Sources */, E73CDABD23A7316700D262E0 /* main.c in Sources */, E73CDABE23A7316700D262E0 /* run_tests.c in Sources */, + E77483632820A94B00B352ED /* t_cose_austere_test.c in Sources */, E73CDABF23A7316700D262E0 /* t_cose_sign1_sign.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -640,9 +658,11 @@ E72FB01D231ADAA8000970FE /* run_tests.c in Sources */, E721CB9A2362ABA400C7FD56 /* t_cose_make_openssl_test_key.c in Sources */, E7E36EA5226CBB570040613B /* t_cose_openssl_crypto.c in Sources */, + E77483622820A94B00B352ED /* t_cose_austere_test.c in Sources */, 0F91057A2321878F00008572 /* t_cose_parameters.c in Sources */, 0F8B2FEF2345A33A00A22349 /* t_cose_make_test_messages.c in Sources */, E7E36E90226CB9460040613B /* t_cose_util.c in Sources */, + E774835C28209B3200B352ED /* t_cose_austere_sign.c in Sources */, E721CB9B2362AC2A00C7FD56 /* t_cose_sign_verify_test.c in Sources */, E7F70AC62270DFAE007CE07F /* t_cose_test.c in Sources */, E7E36E7C226CB8400040613B /* main.c in Sources */, diff --git a/test/run_tests.c b/test/run_tests.c index 8e71490b..3b0f5a41 100644 --- a/test/run_tests.c +++ b/test/run_tests.c @@ -17,6 +17,7 @@ #include "t_cose_test.h" #include "t_cose_sign_verify_test.h" +#include "t_cose_austere_test.h" /* @@ -62,6 +63,7 @@ static test_entry s_tests[] = { TEST_ENTRY(sign_verify_sig_fail_test), TEST_ENTRY(sign_verify_get_size_test), TEST_ENTRY(known_good_test), + TEST_ENTRY(austere_test), #endif /* T_COSE_DISABLE_SIGN_VERIFY_TESTS */ #ifndef T_COSE_DISABLE_SHORT_CIRCUIT_SIGN diff --git a/test/t_cose_austere_test.c b/test/t_cose_austere_test.c new file mode 100644 index 00000000..85f39ac5 --- /dev/null +++ b/test/t_cose_austere_test.c @@ -0,0 +1,63 @@ +// +// t_cose_austere_test.c +// t_cose +// +// Created by Laurence Lundblade on 5/2/22. +// Copyright © 2022 Laurence Lundblade. All rights reserved. +// + +#include "t_cose_austere_test.h" +#include "t_cose_make_test_pub_key.h" + +#include "t_cose/t_cose_austere_sign.h" +#include "t_cose/t_cose_sign1_verify.h" + +const uint8_t payload[] = { + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03 +}; + + +int32_t austere_test(void) { + + enum t_cose_err_t err; + MakeUsefulBufOnStack(output, 250); + struct q_useful_buf_c cose_sign1; + + struct t_cose_key key_pair; + + err = make_ecdsa_key_pair(T_COSE_ALGORITHM_ES384, &key_pair); + + + err = t_cose_austere_sign(Q_USEFUL_BUF_FROM_BYTE_ARRAY_LITERAL(payload), + key_pair, + output, + &cose_sign1); + + + struct t_cose_sign1_verify_ctx verify_ctx; + + t_cose_sign1_verify_init(&verify_ctx, 0); + + t_cose_sign1_set_verification_key(&verify_ctx, key_pair); + + struct q_useful_buf_c xx; + err = t_cose_sign1_verify(&verify_ctx, cose_sign1, + &xx, NULL); + + return 0; +} diff --git a/test/t_cose_austere_test.h b/test/t_cose_austere_test.h new file mode 100644 index 00000000..52ba1a9c --- /dev/null +++ b/test/t_cose_austere_test.h @@ -0,0 +1,17 @@ +// +// t_cose_austere_test.h +// t_cose +// +// Created by Laurence Lundblade on 5/2/22. +// Copyright © 2022 Laurence Lundblade. All rights reserved. +// + +#ifndef t_cose_austere_test_h +#define t_cose_austere_test_h + + +#include + +int32_t austere_test(void); + +#endif /* t_cose_austere_test_h */ From 5b74bb23e9dd55fe7154a46b6ba642b6eba6ab1a Mon Sep 17 00:00:00 2001 From: Laurence Lundblade Date: Thu, 19 May 2022 16:44:29 -0700 Subject: [PATCH 02/11] a little more work: --- Makefile.ossl | 2 +- ...cose_austere_sign.h => t_cose_mini_sign.h} | 2 +- src/t_cose_austere_sign.c | 135 -------- src/t_cose_mini_sign.c | 317 ++++++++++++++++++ test/t_cose_austere_test.c | 4 +- 5 files changed, 321 insertions(+), 139 deletions(-) rename inc/t_cose/{t_cose_austere_sign.h => t_cose_mini_sign.h} (93%) delete mode 100644 src/t_cose_austere_sign.c create mode 100644 src/t_cose_mini_sign.c diff --git a/Makefile.ossl b/Makefile.ossl index 9e6e6590..40267184 100644 --- a/Makefile.ossl +++ b/Makefile.ossl @@ -62,7 +62,7 @@ INC=-I inc -I test -I src ALL_INC=$(INC) $(CRYPTO_INC) $(QCBOR_INC) CFLAGS=$(CMD_LINE) $(ALL_INC) $(C_OPTS) $(TEST_CONFIG_OPTS) $(CRYPTO_CONFIG_OPTS) -SRC_OBJ=src/t_cose_sign1_verify.o src/t_cose_sign1_sign.o src/t_cose_austere_sign.o src/t_cose_util.o src/t_cose_parameters.o +SRC_OBJ=src/t_cose_sign1_verify.o src/t_cose_sign1_sign.o src/t_cose_mini_sign.o src/t_cose_util.o src/t_cose_parameters.o .PHONY: all install install_headers install_so uninstall clean diff --git a/inc/t_cose/t_cose_austere_sign.h b/inc/t_cose/t_cose_mini_sign.h similarity index 93% rename from inc/t_cose/t_cose_austere_sign.h rename to inc/t_cose/t_cose_mini_sign.h index 19f9862f..4c8b7a2a 100644 --- a/inc/t_cose/t_cose_austere_sign.h +++ b/inc/t_cose/t_cose_mini_sign.h @@ -21,7 +21,7 @@ * */ enum t_cose_err_t -t_cose_austere_sign(struct q_useful_buf_c payload, +t_cose_mini_sign(struct q_useful_buf_c payload, struct t_cose_key signing_key, struct q_useful_buf output_buffer, struct q_useful_buf_c *output); diff --git a/src/t_cose_austere_sign.c b/src/t_cose_austere_sign.c deleted file mode 100644 index e492274f..00000000 --- a/src/t_cose_austere_sign.c +++ /dev/null @@ -1,135 +0,0 @@ -// -// t_cose_austere_sign.c -// t_cose -// -// Created by Laurence Lundblade on 5/2/22. -// Copyright © 2022 Laurence Lundblade. All rights reserved. -// - -#include "t_cose/t_cose_austere_sign.h" -#include "t_cose/t_cose_common.h" - -/* - 1) start the hash function - - 2) hash the fixed byte string that is start of the Sig_structure - - 3) hash the payload - - 4) finish the hash - - 5) copy the COSE_Sign1 stuff before the payload to the output. - - 6) copy the payload to the output - - 7) copy another fixed length string to the output, the bstr head for the signature - - 7) call ECDA sign with the hash as input and output directly to the output buffer - */ - - -#include "t_cose_crypto.h" - -// Adjust these for algorithm and payload length -#define PAYLOAD_LEN 128 // Only works for lengths > 24 and < 256 -#define COSE_HASH COSE_ALGORITHM_SHA_384 -#define ENCODED_EC384 0x22 // Make sure this is the right encoding if you change this -#define ENCODED_EC384_SIG_LEN 96 // Make sure this is the right encoding if you change this - - -/* This has all sort of stuff packed in and hard coded, including the payload length. - - * Sig_structure = [ - * context : "Signature" / "Signature1" / "CounterSignature", - * body_protected : empty_or_serialized_map, - * ? sign_protected : empty_or_serialized_map, - * external_aad : bstr, - * payload : bstr - * ] - - */ - -static uint8_t start_sig_struct[] = { - 0x84, - 0x6A, - 'S', 'i', 'g', 'n', 'a', 't', 'u', 'r', 'e', '1', - 0x44, 0xA1, 0x01, 0x38, ENCODED_EC384, // bstr wrapped protected header wtih algorithm ID - 0x40, // Empty bstr for aad - 0x58, PAYLOAD_LEN, -}; - -static uint8_t start_cose_sign1[] = { - 0x84, - 0x44, 0xA1, 0x01, 0x38, ENCODED_EC384, // bstr wrapped protected header wtih algorithm ID - 0xa0, // no unprotected headers, put some here if you want - 0x58, PAYLOAD_LEN, -}; - -static uint8_t cose_sign1_sig_start[] = { - 0x58, 96 -}; - - - -enum t_cose_err_t -t_cose_austere_sign(const struct q_useful_buf_c payload, - struct t_cose_key signing_key, - const struct q_useful_buf output_buffer, - struct q_useful_buf_c *output) -{ - - struct t_cose_crypto_hash hash_ctx; - enum t_cose_err_t err; - struct q_useful_buf_c computed_hash; - struct q_useful_buf_c signature; - size_t cose_sign1_len; - - - MakeUsefulBufOnStack(hash_output, 64); // TODO: correct size for selected hash - - /* --- hash the Sig_structure --- */ - err = t_cose_crypto_hash_start(&hash_ctx, COSE_ALGORITHM_SHA_384); - - t_cose_crypto_hash_update(&hash_ctx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(start_sig_struct)); - t_cose_crypto_hash_update(&hash_ctx, payload); - - err = t_cose_crypto_hash_finish(&hash_ctx, hash_output, &computed_hash); - - - /* --- Copy first part of COSE_Sign1 to output buffer -- */ - cose_sign1_len = 0; - - const struct q_useful_buf_c xx = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(start_cose_sign1); - q_useful_buf_copy(output_buffer, xx); - - cose_sign1_len += xx.len; - - /* -- Copy the payload to the output buffer -- */ - useful_buf_copy_offset(output_buffer, cose_sign1_len, payload); - - cose_sign1_len += payload.len; - - /* -- Do the signing and put it in the output buffer */ - const struct q_useful_buf_c yy = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(cose_sign1_sig_start); - - useful_buf_copy_offset(output_buffer, cose_sign1_len, yy); - - cose_sign1_len += yy.len; - - struct q_useful_buf tmp = {(uint8_t *)output_buffer.ptr + cose_sign1_len, - output_buffer.len - cose_sign1_len}; - - - t_cose_crypto_sign(T_COSE_ALGORITHM_ES384, - signing_key, - computed_hash, - tmp, - &signature); - - cose_sign1_len += signature.len; - - output->ptr = output_buffer.ptr; - output->len = cose_sign1_len; - - return 0; -} diff --git a/src/t_cose_mini_sign.c b/src/t_cose_mini_sign.c new file mode 100644 index 00000000..d8915e56 --- /dev/null +++ b/src/t_cose_mini_sign.c @@ -0,0 +1,317 @@ +// +// t_cose_austere_sign.c +// t_cose +// +// Created by Laurence Lundblade on 5/2/22. +// Copyright © 2022 Laurence Lundblade. All rights reserved. +// + +#include "t_cose/t_cose_mini_sign.h" +#include "t_cose/t_cose_common.h" +#include "t_cose_crypto.h" + +#include "qcbor/qcbor_encode.h" /* Only uses the function QCBOREncode_EncodeHead()*/ +#include "qcbor/UsefulBuf.h" + +/* + 1) start the hash function + + 2) hash the fixed byte string that is start of the Sig_structure + + 3) hash the payload + + 4) finish the hash + + 5) copy the COSE_Sign1 stuff before the payload to the output. + + 6) copy the payload to the output + + 7) copy another fixed length string to the output, the bstr head for the signature + + 7) call ECDA sign with the hash as input and output directly to the output buffer + */ + + + +// Adjust these for algorithm and payload length +#define PAYLOAD_LEN 128 // Only works for lengths > 24 and < 256 +#define COSE_HASH COSE_ALGORITHM_SHA_384 +#define ENCODED_EC384 0x22 // Make sure this is the right encoding if you change this +#define ENCODED_EC384_SIG_LEN 96 // Make sure this is the right encoding if you change this + + +/* This has all sort of stuff packed in and hard coded, including the payload length. + + * Sig_structure = [ + * context : "Signature" / "Signature1" / "CounterSignature", + * body_protected : empty_or_serialized_map, + * ? sign_protected : empty_or_serialized_map, + * external_aad : bstr, + * payload : bstr + * ] + + */ + +static uint8_t start_sig_struct[] = { + 0x84, + 0x6A, + 'S', 'i', 'g', 'n', 'a', 't', 'u', 'r', 'e', '1', + 0x44, 0xA1, 0x01, 0x38, ENCODED_EC384, // bstr wrapped protected header wtih algorithm ID + 0x40, // Empty bstr for aad +}; + +static uint8_t start_cose_sign1[] = { + 0x84, + 0x44, 0xA1, 0x01, 0x38, ENCODED_EC384, // bstr wrapped protected header wtih algorithm ID + 0xa0, // no unprotected headers, put some here if you want +}; + +static uint8_t cose_sign1_sig_start[] = { + 0x58, ENCODED_EC384_SIG_LEN +}; + + +/* Len > 24 and < 65355 */ +static inline struct q_useful_buf_c +EncodeBstrHead(struct q_useful_buf b, size_t len) +{ + uint8_t *bb = b.ptr; + + if(b.len < 3) { + return NULLUsefulBufC; + } + + if(len < 24 ) { + bb[0] = 0x40 + (uint8_t)len; + return (struct q_useful_buf_c){bb, 1}; + } else if(len < 256) { + bb[0] = 0x58; + bb[1] = (uint8_t)len; + return (struct q_useful_buf_c){bb, 2}; + } else if(len < UINT16_MAX) { + bb[0] = 0x59; + bb[1] = (uint8_t)(len / 8); + bb[2] = (uint8_t)(len % 256); + return (struct q_useful_buf_c){bb, 3}; + } else { + return NULLUsefulBufC; + } +} + + +typedef struct { + UsefulBuf Storage; + size_t uPosition; +} SAP; + +static inline void +init(SAP *pOut, struct q_useful_buf o) +{ + pOut->Storage = o; +} + +static inline void +simple_append(SAP *pOut, const UsefulBufC data) +{ + if(pOut->Storage.len - pOut->uPosition < data.len) { + return; + } + + memcpy((uint8_t *)(pOut->Storage.ptr) + pOut->uPosition, data.ptr, data.len); + + pOut->uPosition += data.len; +} + +static inline struct q_useful_buf +get_place(SAP *pOut) +{ + return (struct q_useful_buf){(uint8_t *)(pOut->Storage.ptr) + pOut->uPosition, + pOut->Storage.len - pOut->uPosition}; +} + + +static inline void advance(SAP *pOut, size_t len) +{ + pOut->uPosition += len; +} + +static inline struct q_useful_buf_c +geto(SAP *pOut) +{ + return (struct q_useful_buf_c){pOut->Storage.ptr, pOut->Storage.len}; +} + + + + + + + +enum t_cose_err_t +t_cose_mini_sign(const struct q_useful_buf_c payload, + struct t_cose_key signing_key, + const struct q_useful_buf output_buffer, + struct q_useful_buf_c *output) +{ + + struct t_cose_crypto_hash hash_ctx; + enum t_cose_err_t err; + struct q_useful_buf_c computed_hash; + struct q_useful_buf_c signature; + MakeUsefulBufOnStack( hash_output, 64); // TODO: correct size for selected hash + MakeUsefulBufOnStack( payload_head_buffer, QCBOR_HEAD_BUFFER_SIZE); + struct q_useful_buf_c payload_head; + struct q_useful_buf tmp; + + payload_head = EncodeBstrHead(payload_head_buffer, payload.len); + + + /* --- hash the Sig_structure --- */ + /* Don't actually have to create the Sig_structure fully in + * memory. Just have to compute the hash of it. */ + err = t_cose_crypto_hash_start(&hash_ctx, COSE_ALGORITHM_SHA_384); + + t_cose_crypto_hash_update(&hash_ctx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(start_sig_struct)); + t_cose_crypto_hash_update(&hash_ctx, payload_head); + t_cose_crypto_hash_update(&hash_ctx, payload); + + err = t_cose_crypto_hash_finish(&hash_ctx, hash_output, &computed_hash); + + + if(output_buffer.len < payload.len + 4 + sizeof(start_cose_sign1) + sizeof(cose_sign1_sig_start)) { + return 0; + } + + uint8_t *p; + + p = output_buffer.ptr; + + memcpy(p, start_cose_sign1, sizeof(start_cose_sign1)); + p += sizeof(start_cose_sign1); + + memcpy(p, payload_head.ptr, payload_head.len); + p += payload_head.len; + + memcpy(p, payload_head.ptr, payload.len); + p += payload.len; + + memcpy(p, cose_sign1_sig_start, sizeof(cose_sign1_sig_start)); + p += payload.len; + + struct q_useful_buf tmp2; + tmp2.len = p - (uint8_t *)output_buffer.ptr ; + tmp.ptr = p; + + + t_cose_crypto_sign(T_COSE_ALGORITHM_ES384, + signing_key, + computed_hash, + tmp, + &signature); + + output->ptr = output_buffer.ptr; + output->len = tmp2.len + ENCODED_EC384_SIG_LEN; + + + return 0; +} + +int foo() +{ + return 99; +} + + +#ifdef NODEF +#if 0 +/* + SAP UBO; + + init(&UBO, output_buffer); + + simple_append(&UBO, Q_USEFUL_BUF_FROM_BYTE_ARRAY_LITERAL(start_cose_sign1)); + simple_append(&UBO, payload_head); + simple_append(&UBO, payload); + simple_append(&UBO, Q_USEFUL_BUF_FROM_BYTE_ARRAY_LITERAL(cose_sign1_sig_start)); + + // Output the signature directly into the output buffer. + tmp = get_place(&UBO); + + t_cose_crypto_sign(T_COSE_ALGORITHM_ES384, + signing_key, + computed_hash, + tmp, + &signature); + + advance(&UBO, signature.len); + + *output = geto(&UBO);*/ + +#else + + + UsefulOutBuf UBO; + + UsefulOutBuf_Init(&UBO, output_buffer); + + UsefulOutBuf_AppendUsefulBuf(&UBO, Q_USEFUL_BUF_FROM_BYTE_ARRAY_LITERAL(start_cose_sign1)); + UsefulOutBuf_AppendUsefulBuf(&UBO, payload_head); + UsefulOutBuf_AppendUsefulBuf(&UBO, payload); + UsefulOutBuf_AppendUsefulBuf(&UBO, Q_USEFUL_BUF_FROM_BYTE_ARRAY_LITERAL(cose_sign1_sig_start)); + + /* Output the signature directly into the output buffer. */ + tmp = UsefulOutBuf_GetOutPlace(&UBO); + + t_cose_crypto_sign(T_COSE_ALGORITHM_ES384, + signing_key, + computed_hash, + tmp, + &signature); + + UsefulOutBuf_Advance(&UBO, signature.len); + + *output = UsefulOutBuf_OutUBuf(&UBO); + + + +//#else + size_t cose_sign1_len; + /* --- Copy first part of COSE_Sign1 to output buffer -- */ + cose_sign1_len = 0; + + const struct q_useful_buf_c xx = Q_USEFUL_BUF_FROM_BYTE_ARRAY_LITERAL(start_cose_sign1); + q_useful_buf_copy(output_buffer, + UsefulBuf_FROM_BYTE_ARRAY_LITERAL(start_cose_sign1)); + cose_sign1_len += xx.len; + + + useful_buf_copy_offset(output_buffer, cose_sign1_len, payload_head); + cose_sign1_len += payload_head.len; + + + /* -- Copy the payload to the output buffer -- */ + useful_buf_copy_offset(output_buffer, cose_sign1_len, payload); + cose_sign1_len += payload.len; + + /* -- Do the signing and put it in the output buffer */ + const struct q_useful_buf_c yy = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(cose_sign1_sig_start); + useful_buf_copy_offset(output_buffer, cose_sign1_len, yy); + cose_sign1_len += yy.len; + + tmp = (struct q_useful_buf){(uint8_t *)output_buffer.ptr + cose_sign1_len, + output_buffer.len - cose_sign1_len}; + + + t_cose_crypto_sign(T_COSE_ALGORITHM_ES384, + signing_key, + computed_hash, + tmp, + &signature); + + cose_sign1_len += signature.len; + + output->ptr = output_buffer.ptr; + output->len = cose_sign1_len; + +#endif +#endif diff --git a/test/t_cose_austere_test.c b/test/t_cose_austere_test.c index 85f39ac5..4984b185 100644 --- a/test/t_cose_austere_test.c +++ b/test/t_cose_austere_test.c @@ -9,7 +9,7 @@ #include "t_cose_austere_test.h" #include "t_cose_make_test_pub_key.h" -#include "t_cose/t_cose_austere_sign.h" +#include "t_cose/t_cose_mini_sign.h" #include "t_cose/t_cose_sign1_verify.h" const uint8_t payload[] = { @@ -43,7 +43,7 @@ int32_t austere_test(void) { err = make_ecdsa_key_pair(T_COSE_ALGORITHM_ES384, &key_pair); - err = t_cose_austere_sign(Q_USEFUL_BUF_FROM_BYTE_ARRAY_LITERAL(payload), + err = t_cose_mini_sign(Q_USEFUL_BUF_FROM_BYTE_ARRAY_LITERAL(payload), key_pair, output, &cose_sign1); From b3d9d5cf223fb8805d9654ae3c8ce22e523d434d Mon Sep 17 00:00:00 2001 From: Laurence Lundblade Date: Tue, 24 May 2022 12:12:21 -0700 Subject: [PATCH 03/11] checkpoint mini sign work --- src/t_cose_mini_sign.c | 228 +++++++------------------------ t_cose.xcodeproj/project.pbxproj | 20 +-- 2 files changed, 60 insertions(+), 188 deletions(-) diff --git a/src/t_cose_mini_sign.c b/src/t_cose_mini_sign.c index d8915e56..59578e47 100644 --- a/src/t_cose_mini_sign.c +++ b/src/t_cose_mini_sign.c @@ -1,5 +1,5 @@ // -// t_cose_austere_sign.c +// t_cose_mini_sign.c // t_cose // // Created by Laurence Lundblade on 5/2/22. @@ -10,35 +10,39 @@ #include "t_cose/t_cose_common.h" #include "t_cose_crypto.h" -#include "qcbor/qcbor_encode.h" /* Only uses the function QCBOREncode_EncodeHead()*/ #include "qcbor/UsefulBuf.h" -/* - 1) start the hash function - 2) hash the fixed byte string that is start of the Sig_structure +#define T_COSE_MINI_SIGN_SELECT_ES384 - 3) hash the payload - 4) finish the hash - 5) copy the COSE_Sign1 stuff before the payload to the output. - 6) copy the payload to the output +#if defined(T_COSE_MINI_SIGN_SELECT_ES256) - 7) copy another fixed length string to the output, the bstr head for the signature +#define MINI_SIGN_HASH COSE_ALGORITHM_SHA_256 +#define MINI_SIGN_HASH_LEN T_COSE_CRYPTO_SHA256_SIZE +#define MINI_SIGN_ALG T_COSE_ALGORITHM_ES256 +#define MINI_SIGN_ALG_ID_BYTES 0x26 /* The literal byte that appears in the CBOR encoding */ +#define MINI_SIGN_SIG_LEN T_COSE_EC_P256_SIG_SIZE // Code below only works for lengths < 256 - 7) call ECDA sign with the hash as input and output directly to the output buffer - */ +#elif defined(T_COSE_MINI_SIGN_SELECT_ES384) +#define MINI_SIGN_HASH COSE_ALGORITHM_SHA_384 +#define MINI_SIGN_HASH_LEN T_COSE_CRYPTO_SHA384_SIZE +#define MINI_SIGN_ALG T_COSE_ALGORITHM_ES384 +#define MINI_SIGN_ALG_ID_BYTES 0x38, 0x22 /* The literal byte that appears in the CBOR encoding */ +#define MINI_SIGN_SIG_LEN T_COSE_EC_P384_SIG_SIZE // Code below only works for lengths < 256 +#elif defined(T_COSE_MINI_SIGN_SELECT_ES512) -// Adjust these for algorithm and payload length -#define PAYLOAD_LEN 128 // Only works for lengths > 24 and < 256 -#define COSE_HASH COSE_ALGORITHM_SHA_384 -#define ENCODED_EC384 0x22 // Make sure this is the right encoding if you change this -#define ENCODED_EC384_SIG_LEN 96 // Make sure this is the right encoding if you change this +#define MINI_SIGN_HASH COSE_ALGORITHM_SHA_512 +#define MINI_SIGN_HASH_LEN T_COSE_CRYPTO_SHA512_SIZE +#define MINI_SIGN_ALG T_COSE_ALGORITHM_ES521 +#define MINI_SIGN_ALG_ID_BYTES 0x38, 0x23 /* The literal byte that appears in the CBOR encoding */ +#define MINI_SIGN_SIG_LEN T_COSE_EC_P512_SIG_SIZE // Code below only works for lengths < 256 +#endif /* This has all sort of stuff packed in and hard coded, including the payload length. @@ -54,30 +58,35 @@ static uint8_t start_sig_struct[] = { 0x84, - 0x6A, - 'S', 'i', 'g', 'n', 'a', 't', 'u', 'r', 'e', '1', - 0x44, 0xA1, 0x01, 0x38, ENCODED_EC384, // bstr wrapped protected header wtih algorithm ID + 0x6A,'S', 'i', 'g', 'n', 'a', 't', 'u', 'r', 'e', '1', + 0x44, 0xA1, 0x01, MINI_SIGN_ALG_ID_BYTES, // bstr wrapped protected header wtih algorithm ID 0x40, // Empty bstr for aad }; static uint8_t start_cose_sign1[] = { 0x84, - 0x44, 0xA1, 0x01, 0x38, ENCODED_EC384, // bstr wrapped protected header wtih algorithm ID + 0x44, 0xA1, 0x01, MINI_SIGN_ALG_ID_BYTES, // bstr wrapped protected header wtih algorithm ID 0xa0, // no unprotected headers, put some here if you want }; static uint8_t cose_sign1_sig_start[] = { - 0x58, ENCODED_EC384_SIG_LEN + 0x58, MINI_SIGN_SIG_LEN }; -/* Len > 24 and < 65355 */ + + +/* This maximum is for a CBOR head for a byte string no longer than + * UINT16_MAX, not the general case for a CBOR head. */ +#define MAX_CBOR_HEAD 3 + +/* Len < 65355 */ static inline struct q_useful_buf_c -EncodeBstrHead(struct q_useful_buf b, size_t len) +encode_bstr_head(struct q_useful_buf b, size_t len) { uint8_t *bb = b.ptr; - if(b.len < 3) { + if(b.len < MAX_CBOR_HEAD) { return NULLUsefulBufC; } @@ -99,52 +108,6 @@ EncodeBstrHead(struct q_useful_buf b, size_t len) } -typedef struct { - UsefulBuf Storage; - size_t uPosition; -} SAP; - -static inline void -init(SAP *pOut, struct q_useful_buf o) -{ - pOut->Storage = o; -} - -static inline void -simple_append(SAP *pOut, const UsefulBufC data) -{ - if(pOut->Storage.len - pOut->uPosition < data.len) { - return; - } - - memcpy((uint8_t *)(pOut->Storage.ptr) + pOut->uPosition, data.ptr, data.len); - - pOut->uPosition += data.len; -} - -static inline struct q_useful_buf -get_place(SAP *pOut) -{ - return (struct q_useful_buf){(uint8_t *)(pOut->Storage.ptr) + pOut->uPosition, - pOut->Storage.len - pOut->uPosition}; -} - - -static inline void advance(SAP *pOut, size_t len) -{ - pOut->uPosition += len; -} - -static inline struct q_useful_buf_c -geto(SAP *pOut) -{ - return (struct q_useful_buf_c){pOut->Storage.ptr, pOut->Storage.len}; -} - - - - - enum t_cose_err_t @@ -153,23 +116,26 @@ t_cose_mini_sign(const struct q_useful_buf_c payload, const struct q_useful_buf output_buffer, struct q_useful_buf_c *output) { - struct t_cose_crypto_hash hash_ctx; enum t_cose_err_t err; struct q_useful_buf_c computed_hash; struct q_useful_buf_c signature; - MakeUsefulBufOnStack( hash_output, 64); // TODO: correct size for selected hash - MakeUsefulBufOnStack( payload_head_buffer, QCBOR_HEAD_BUFFER_SIZE); + MakeUsefulBufOnStack( hash_output, MINI_SIGN_HASH_LEN); + MakeUsefulBufOnStack( payload_head_buffer, MAX_CBOR_HEAD); struct q_useful_buf_c payload_head; struct q_useful_buf tmp; - payload_head = EncodeBstrHead(payload_head_buffer, payload.len); + payload_head = encode_bstr_head(payload_head_buffer, payload.len); + + if(payload_head.ptr == NULL) { + return 99; // TODO: error code + } /* --- hash the Sig_structure --- */ /* Don't actually have to create the Sig_structure fully in * memory. Just have to compute the hash of it. */ - err = t_cose_crypto_hash_start(&hash_ctx, COSE_ALGORITHM_SHA_384); + err = t_cose_crypto_hash_start(&hash_ctx, MINI_SIGN_HASH); t_cose_crypto_hash_update(&hash_ctx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(start_sig_struct)); t_cose_crypto_hash_update(&hash_ctx, payload_head); @@ -178,7 +144,12 @@ t_cose_mini_sign(const struct q_useful_buf_c payload, err = t_cose_crypto_hash_finish(&hash_ctx, hash_output, &computed_hash); - if(output_buffer.len < payload.len + 4 + sizeof(start_cose_sign1) + sizeof(cose_sign1_sig_start)) { + const size_t required_len = payload.len + + MAX_CBOR_HEAD + + sizeof(start_cose_sign1) + + sizeof(cose_sign1_sig_start); + + if(output_buffer.len < required_len) { return 0; } @@ -203,115 +174,16 @@ t_cose_mini_sign(const struct q_useful_buf_c payload, tmp.ptr = p; - t_cose_crypto_sign(T_COSE_ALGORITHM_ES384, + t_cose_crypto_sign(MINI_SIGN_ALG, signing_key, computed_hash, tmp, &signature); output->ptr = output_buffer.ptr; - output->len = tmp2.len + ENCODED_EC384_SIG_LEN; + output->len = tmp2.len + MINI_SIGN_SIG_LEN; return 0; } -int foo() -{ - return 99; -} - - -#ifdef NODEF -#if 0 -/* - SAP UBO; - - init(&UBO, output_buffer); - - simple_append(&UBO, Q_USEFUL_BUF_FROM_BYTE_ARRAY_LITERAL(start_cose_sign1)); - simple_append(&UBO, payload_head); - simple_append(&UBO, payload); - simple_append(&UBO, Q_USEFUL_BUF_FROM_BYTE_ARRAY_LITERAL(cose_sign1_sig_start)); - - // Output the signature directly into the output buffer. - tmp = get_place(&UBO); - - t_cose_crypto_sign(T_COSE_ALGORITHM_ES384, - signing_key, - computed_hash, - tmp, - &signature); - - advance(&UBO, signature.len); - - *output = geto(&UBO);*/ - -#else - - - UsefulOutBuf UBO; - - UsefulOutBuf_Init(&UBO, output_buffer); - - UsefulOutBuf_AppendUsefulBuf(&UBO, Q_USEFUL_BUF_FROM_BYTE_ARRAY_LITERAL(start_cose_sign1)); - UsefulOutBuf_AppendUsefulBuf(&UBO, payload_head); - UsefulOutBuf_AppendUsefulBuf(&UBO, payload); - UsefulOutBuf_AppendUsefulBuf(&UBO, Q_USEFUL_BUF_FROM_BYTE_ARRAY_LITERAL(cose_sign1_sig_start)); - - /* Output the signature directly into the output buffer. */ - tmp = UsefulOutBuf_GetOutPlace(&UBO); - - t_cose_crypto_sign(T_COSE_ALGORITHM_ES384, - signing_key, - computed_hash, - tmp, - &signature); - - UsefulOutBuf_Advance(&UBO, signature.len); - - *output = UsefulOutBuf_OutUBuf(&UBO); - - - -//#else - size_t cose_sign1_len; - /* --- Copy first part of COSE_Sign1 to output buffer -- */ - cose_sign1_len = 0; - - const struct q_useful_buf_c xx = Q_USEFUL_BUF_FROM_BYTE_ARRAY_LITERAL(start_cose_sign1); - q_useful_buf_copy(output_buffer, - UsefulBuf_FROM_BYTE_ARRAY_LITERAL(start_cose_sign1)); - cose_sign1_len += xx.len; - - - useful_buf_copy_offset(output_buffer, cose_sign1_len, payload_head); - cose_sign1_len += payload_head.len; - - - /* -- Copy the payload to the output buffer -- */ - useful_buf_copy_offset(output_buffer, cose_sign1_len, payload); - cose_sign1_len += payload.len; - - /* -- Do the signing and put it in the output buffer */ - const struct q_useful_buf_c yy = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(cose_sign1_sig_start); - useful_buf_copy_offset(output_buffer, cose_sign1_len, yy); - cose_sign1_len += yy.len; - - tmp = (struct q_useful_buf){(uint8_t *)output_buffer.ptr + cose_sign1_len, - output_buffer.len - cose_sign1_len}; - - - t_cose_crypto_sign(T_COSE_ALGORITHM_ES384, - signing_key, - computed_hash, - tmp, - &signature); - - cose_sign1_len += signature.len; - - output->ptr = output_buffer.ptr; - output->len = cose_sign1_len; - -#endif -#endif diff --git a/t_cose.xcodeproj/project.pbxproj b/t_cose.xcodeproj/project.pbxproj index ae32e5b9..bd4d0e72 100644 --- a/t_cose.xcodeproj/project.pbxproj +++ b/t_cose.xcodeproj/project.pbxproj @@ -60,9 +60,9 @@ E772027C23CAEC84006E966E /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = E7E36E7B226CB8400040613B /* main.c */; }; E772027D23CAEC84006E966E /* run_tests.c in Sources */ = {isa = PBXBuildFile; fileRef = E72FB01C231ADAA8000970FE /* run_tests.c */; }; E772027E23CAEC84006E966E /* t_cose_sign1_sign.c in Sources */ = {isa = PBXBuildFile; fileRef = E7E36E8E226CB9460040613B /* t_cose_sign1_sign.c */; }; - E774835B28209B3200B352ED /* t_cose_austere_sign.c in Sources */ = {isa = PBXBuildFile; fileRef = E774835A28209B3200B352ED /* t_cose_austere_sign.c */; }; - E774835C28209B3200B352ED /* t_cose_austere_sign.c in Sources */ = {isa = PBXBuildFile; fileRef = E774835A28209B3200B352ED /* t_cose_austere_sign.c */; }; - E774835D28209B3200B352ED /* t_cose_austere_sign.c in Sources */ = {isa = PBXBuildFile; fileRef = E774835A28209B3200B352ED /* t_cose_austere_sign.c */; }; + E774835B28209B3200B352ED /* t_cose_mini_sign.c in Sources */ = {isa = PBXBuildFile; fileRef = E774835A28209B3200B352ED /* t_cose_mini_sign.c */; }; + E774835C28209B3200B352ED /* t_cose_mini_sign.c in Sources */ = {isa = PBXBuildFile; fileRef = E774835A28209B3200B352ED /* t_cose_mini_sign.c */; }; + E774835D28209B3200B352ED /* t_cose_mini_sign.c in Sources */ = {isa = PBXBuildFile; fileRef = E774835A28209B3200B352ED /* t_cose_mini_sign.c */; }; E77483612820A94B00B352ED /* t_cose_austere_test.c in Sources */ = {isa = PBXBuildFile; fileRef = E77483602820A94B00B352ED /* t_cose_austere_test.c */; }; E77483622820A94B00B352ED /* t_cose_austere_test.c in Sources */ = {isa = PBXBuildFile; fileRef = E77483602820A94B00B352ED /* t_cose_austere_test.c */; }; E77483632820A94B00B352ED /* t_cose_austere_test.c in Sources */ = {isa = PBXBuildFile; fileRef = E77483602820A94B00B352ED /* t_cose_austere_test.c */; }; @@ -193,8 +193,8 @@ E751F9EE27E1F85000EBA5FA /* crypto_values.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = crypto_values.h; path = ../../../../../usr/local/include/psa/crypto_values.h; sourceTree = ""; }; E751F9F027E1F90F00EBA5FA /* libmbedcrypto.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmbedcrypto.a; path = ../../../../../usr/local/lib/libmbedcrypto.a; sourceTree = ""; }; E772028523CAEC84006E966E /* t_cose_psa_noss */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = t_cose_psa_noss; sourceTree = BUILT_PRODUCTS_DIR; }; - E774835A28209B3200B352ED /* t_cose_austere_sign.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = t_cose_austere_sign.c; sourceTree = ""; }; - E774835E28209BC500B352ED /* t_cose_austere_sign.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = t_cose_austere_sign.h; path = t_cose/t_cose_austere_sign.h; sourceTree = ""; }; + E774835A28209B3200B352ED /* t_cose_mini_sign.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = t_cose_mini_sign.c; sourceTree = ""; }; + E774835E28209BC500B352ED /* t_cose_mini_sign.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = t_cose_mini_sign.h; path = t_cose/t_cose_mini_sign.h; sourceTree = ""; }; E774835F2820A94B00B352ED /* t_cose_austere_test.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = t_cose_austere_test.h; sourceTree = ""; }; E77483602820A94B00B352ED /* t_cose_austere_test.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = t_cose_austere_test.c; sourceTree = ""; }; E7C960A527F7569500FB537C /* libqcbor.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libqcbor.a; path = ../../../../../usr/local/lib/libqcbor.a; sourceTree = ""; }; @@ -346,7 +346,7 @@ E7E36E82226CB9460040613B /* inc */ = { isa = PBXGroup; children = ( - E774835E28209BC500B352ED /* t_cose_austere_sign.h */, + E774835E28209BC500B352ED /* t_cose_mini_sign.h */, E72EC9EF242E74EE006D3DD3 /* q_useful_buf.h */, E72EC9ED242E74EE006D3DD3 /* t_cose_common.h */, E72EC9EC242E74EE006D3DD3 /* t_cose_sign1_sign.h */, @@ -366,7 +366,7 @@ E7E36E8C226CB9460040613B /* t_cose_util.h */, E7E36E8D226CB9460040613B /* t_cose_crypto.h */, E7E36E8E226CB9460040613B /* t_cose_sign1_sign.c */, - E774835A28209B3200B352ED /* t_cose_austere_sign.c */, + E774835A28209B3200B352ED /* t_cose_mini_sign.c */, ); path = src; sourceTree = ""; @@ -575,7 +575,7 @@ E730E61223612DAB00175CE0 /* t_cose_make_test_messages.c in Sources */, E730E61323612DAB00175CE0 /* t_cose_util.c in Sources */, E730E61523612DAB00175CE0 /* sha256.c in Sources */, - E774835B28209B3200B352ED /* t_cose_austere_sign.c in Sources */, + E774835B28209B3200B352ED /* t_cose_mini_sign.c in Sources */, E730E61623612DAB00175CE0 /* t_cose_test.c in Sources */, E730E61823612DAB00175CE0 /* main.c in Sources */, E77483612820A94B00B352ED /* t_cose_austere_test.c in Sources */, @@ -616,7 +616,7 @@ files = ( E73CDAAE23A7316700D262E0 /* t_cose_sign1_verify.c in Sources */, E73CDAB023A7316700D262E0 /* t_cose_test.c in Sources */, - E774835D28209B3200B352ED /* t_cose_austere_sign.c in Sources */, + E774835D28209B3200B352ED /* t_cose_mini_sign.c in Sources */, E73CDAD423AD4F3900D262E0 /* t_cose_psa_crypto.c in Sources */, E73CDAB223A7316700D262E0 /* t_cose_util.c in Sources */, E73CDAB623A7316700D262E0 /* t_cose_parameters.c in Sources */, @@ -662,7 +662,7 @@ 0F91057A2321878F00008572 /* t_cose_parameters.c in Sources */, 0F8B2FEF2345A33A00A22349 /* t_cose_make_test_messages.c in Sources */, E7E36E90226CB9460040613B /* t_cose_util.c in Sources */, - E774835C28209B3200B352ED /* t_cose_austere_sign.c in Sources */, + E774835C28209B3200B352ED /* t_cose_mini_sign.c in Sources */, E721CB9B2362AC2A00C7FD56 /* t_cose_sign_verify_test.c in Sources */, E7F70AC62270DFAE007CE07F /* t_cose_test.c in Sources */, E7E36E7C226CB8400040613B /* main.c in Sources */, From 2815ac567c43675fff511061e6f86476b36699d7 Mon Sep 17 00:00:00 2001 From: Laurence Lundblade Date: Thu, 26 May 2022 22:46:57 -0500 Subject: [PATCH 04/11] Documentation, bug fixes and other mini sign stuff --- inc/t_cose/t_cose_common.h | 4 + inc/t_cose/t_cose_mini_sign.h | 100 ++++++++++++++---- src/t_cose_mini_sign.c | 187 +++++++++++++++++++++++----------- test/t_cose_austere_test.c | 57 ++++++----- 4 files changed, 246 insertions(+), 102 deletions(-) diff --git a/inc/t_cose/t_cose_common.h b/inc/t_cose/t_cose_common.h index 8741c774..e6c30243 100644 --- a/inc/t_cose/t_cose_common.h +++ b/inc/t_cose/t_cose_common.h @@ -341,6 +341,10 @@ enum t_cose_err_t { /** More than \ref T_COSE_MAX_TAGS_TO_RETURN unprocessed tags when * verifying a signature. */ T_COSE_ERR_TOO_MANY_TAGS = 37, + + /** The size or length is larger than can be handled. */ + T_COSE_ERR_TOO_LONG = 38, + }; diff --git a/inc/t_cose/t_cose_mini_sign.h b/inc/t_cose/t_cose_mini_sign.h index 4c8b7a2a..26067d4c 100644 --- a/inc/t_cose/t_cose_mini_sign.h +++ b/inc/t_cose/t_cose_mini_sign.h @@ -1,30 +1,94 @@ -// -// t_cose_austere_sign.h -// t_cose -// -// Created by Laurence Lundblade on 5/2/22. -// Copyright © 2022 Laurence Lundblade. All rights reserved. -// +/* + * t_cose_mini_sign.h + * + * Copyright 2022, Laurence Lundblade + * + * SPDX-License-Identifier: BSD-3-Clause + * + * See BSD-3-Clause license in README.md + */ -#ifndef t_cose_austere_sign_h -#define t_cose_austere_sign_h +#ifndef __T_COSE_MINI_SIGN_H__ +#define __T_COSE_MINI_SIGN_H__ #include "t_cose/q_useful_buf.h" #include "t_cose/t_cose_common.h" -/* The algorithm ID, and such are defined as hard constants - * in the implementation. - * The payload length is also defined in the implementation - * despite being passed in here in payload.len + +#ifdef __cplusplus +extern "C" { +#if 0 +} /* Keep editor indention formatting happy */ +#endif +#endif + + + +/* The output buffer must be this much larger than the payload size. */ +#define T_COSE_MINI_SIGN_SIZE_OVERHEAD_ES256 \ + 1 + /* Open the array */ \ + 6 + /* The header parameters */ \ + 3 + /* The CBOR head of the payload */ \ + /* The payload -- add this in yourself */ \ + 2 + /* CBOR head of signature */ \ + 64 // T_COSE_EC_P256_SIG_SIZE + +#define T_COSE_MINI_SIGN_SIZE_OVERHEAD_ES384 \ + 1 + /* Open the array */ \ + 6 + /* The header parameters */ \ + 3 + /* The CBOR head of the payload */ \ + /* The payload -- add this in yourself */ \ + 2 + /* CBOR head of signature */ \ + T_COSE_EC_P384_SIG_SIZE + +#define T_COSE_MINI_SIGN_SIZE_OVERHEAD_ES512 \ + 1 + /* Open the array */ \ + 6 + /* The header parameters */ \ + 3 + /* The CBOR head of the payload */ \ + /* The payload -- add this in yourself */ \ + 2 + /* CBOR head of signature */ \ + T_COSE_EC_P512_SIG_SIZE + + +/* + * @brief Create a COSE_Sign1 with fixed algorithm and no header parameters. + * + * @param[in] payload The payload to sign. + * @param[in] signing_key The key to sign with. + * @param[in] output_buffer The buffer where the COSE_Sign1 is written. + * @param[out] output Pointer and length of the completed COSE_Sign1. + * + * @return T_COSE_ERR_TOO_LONG The payload length is > UINT16_MAX + * T_COSE_ERR_TOO_SMALL The output_buffer is too small for the + * payload. + * Other errors related to invocation of the crypto algorithms. * - * + * This is a small object code version of t_cose_sign1_sign(). The + * small object code is achieved by fixing the algorithm at compile + * time (the default is COSE ES256) and by not allowing or outputting + * any header parameter except the algorithm ID. There is also + * a maximum size of the payload at UINT16_MAX. + * + * This is roughly 500 bytes of object code versus 1,500 bytes for + * t_cose_sign1_sign(). + * + * One could modify the source to include fixed COSE header parameters + * or even a variable header parameter like the kid and the object + * code would still be small. I + * + * If modifications are made so the payload is fixed at compile time, + * the object code could be reduced. */ enum t_cose_err_t t_cose_mini_sign(struct q_useful_buf_c payload, - struct t_cose_key signing_key, - struct q_useful_buf output_buffer, - struct q_useful_buf_c *output); + struct t_cose_key signing_key, + struct q_useful_buf output_buffer, + struct q_useful_buf_c *output); + +#ifdef __cplusplus +} +#endif -#endif /* t_cose_austere_sign_h */ +#endif /* __T_COSE_MINI_SIGN_H__ */ diff --git a/src/t_cose_mini_sign.c b/src/t_cose_mini_sign.c index 59578e47..cca3d74d 100644 --- a/src/t_cose_mini_sign.c +++ b/src/t_cose_mini_sign.c @@ -1,10 +1,12 @@ -// -// t_cose_mini_sign.c -// t_cose -// -// Created by Laurence Lundblade on 5/2/22. -// Copyright © 2022 Laurence Lundblade. All rights reserved. -// +/* + * t_cose_mini_sign.c + * + * Copyright 2022, Laurence Lundblade + * + * SPDX-License-Identifier: BSD-3-Clause + * + * See BSD-3-Clause license in README.md + */ #include "t_cose/t_cose_mini_sign.h" #include "t_cose/t_cose_common.h" @@ -12,10 +14,14 @@ #include "qcbor/UsefulBuf.h" +/* +Define one of these to configure the algorithm +#define T_COSE_MINI_SIGN_SELECT_ES256 #define T_COSE_MINI_SIGN_SELECT_ES384 - - +#define T_COSE_MINI_SIGN_SELECT_ES512 +*/ +#define T_COSE_MINI_SIGN_SELECT_ES256 #if defined(T_COSE_MINI_SIGN_SELECT_ES256) @@ -44,53 +50,86 @@ #endif -/* This has all sort of stuff packed in and hard coded, including the payload length. - * Sig_structure = [ - * context : "Signature" / "Signature1" / "CounterSignature", - * body_protected : empty_or_serialized_map, - * ? sign_protected : empty_or_serialized_map, - * external_aad : bstr, - * payload : bstr - * ] +#if defined(T_COSE_MINI_SIGN_SELECT_ES256) +#define PROT_HEADER_START 0x43 +#else +#define PROT_HEADER_START 0x44 +#endif +#define PROT_HEADERS \ + PROT_HEADER_START, \ + 0xA1, 0x01, \ + MINI_SIGN_ALG_ID_BYTES + +/* + * This is hard-coded bytes for the start of the CBOR for the following + * CBOR that are the to-be-signed bytes. Hard coding like this saves + * writing code to create it. + * + * Sig_structure = [ + * context : "Signature" / "Signature1" / "CounterSignature", + * body_protected : empty_or_serialized_map, + * ? sign_protected : empty_or_serialized_map, + * external_aad : bstr, + * payload : bstr + * ] */ - static uint8_t start_sig_struct[] = { 0x84, 0x6A,'S', 'i', 'g', 'n', 'a', 't', 'u', 'r', 'e', '1', - 0x44, 0xA1, 0x01, MINI_SIGN_ALG_ID_BYTES, // bstr wrapped protected header wtih algorithm ID - 0x40, // Empty bstr for aad + PROT_HEADERS, // bstr wrapped protected header wtih algorithm ID + 0x40, /* Empty bstr for aad */ }; +/* The first part of a COSE_Sign1: the opening array, + * the protected parameters and the unproteced parameters. + */ static uint8_t start_cose_sign1[] = { 0x84, - 0x44, 0xA1, 0x01, MINI_SIGN_ALG_ID_BYTES, // bstr wrapped protected header wtih algorithm ID - 0xa0, // no unprotected headers, put some here if you want + PROT_HEADERS, // bstr wrapped protected header wtih algorithm ID + 0xa0, /* no unprotected headers, put some here if you want */ }; +/* The Hard coded bytes for the CBOR head for the signature. It is less + * code to hard code than to encode using encode_bstr_head() */ static uint8_t cose_sign1_sig_start[] = { 0x58, MINI_SIGN_SIG_LEN }; - +#if MINI_SIGN_SIG_LEN > 255 +#error signature length is too long +#endif /* This maximum is for a CBOR head for a byte string no longer than * UINT16_MAX, not the general case for a CBOR head. */ #define MAX_CBOR_HEAD 3 -/* Len < 65355 */ + +/* + * @brief Encode a CBOR head for a byte string of given length + * + * @param[in] len The length to encode. + * @param[in] out_buffer Pointer and length to write to. + * + * @return The pointer and length of the encoded CBOR head + * or \c NULL_Q_USEFUL_BUF_C if @c len is + * greater than 65355. + * + * This is a scaled-down specific version of QCBOREncode_EncodeHead() + * in QCBOR. + */ static inline struct q_useful_buf_c -encode_bstr_head(struct q_useful_buf b, size_t len) +encode_bstr_head(const size_t len, const struct q_useful_buf out_buffer) { - uint8_t *bb = b.ptr; + uint8_t *bb = out_buffer.ptr; - if(b.len < MAX_CBOR_HEAD) { - return NULLUsefulBufC; + if(out_buffer.len < MAX_CBOR_HEAD) { + return NULL_Q_USEFUL_BUF_C; } - if(len < 24 ) { + if(len < 24) { /* 24 is a special number in CBOR */ bb[0] = 0x40 + (uint8_t)len; return (struct q_useful_buf_c){bb, 1}; } else if(len < 256) { @@ -103,13 +142,14 @@ encode_bstr_head(struct q_useful_buf b, size_t len) bb[2] = (uint8_t)(len % 256); return (struct q_useful_buf_c){bb, 3}; } else { - return NULLUsefulBufC; + return NULL_Q_USEFUL_BUF_C; } } - - +/* + * Public function. + */ enum t_cose_err_t t_cose_mini_sign(const struct q_useful_buf_c payload, struct t_cose_key signing_key, @@ -123,12 +163,17 @@ t_cose_mini_sign(const struct q_useful_buf_c payload, MakeUsefulBufOnStack( hash_output, MINI_SIGN_HASH_LEN); MakeUsefulBufOnStack( payload_head_buffer, MAX_CBOR_HEAD); struct q_useful_buf_c payload_head; - struct q_useful_buf tmp; + struct q_useful_buf signature_buffer; + uint8_t *copy_ptr; - payload_head = encode_bstr_head(payload_head_buffer, payload.len); + /* --- Create a CBOR head for the payload ---- */ + payload_head = encode_bstr_head(payload.len, payload_head_buffer); if(payload_head.ptr == NULL) { - return 99; // TODO: error code + /* The payload is too large (the only reason encode_bstr_head() + * errors out. + */ + return T_COSE_ERR_TOO_LONG; } @@ -136,54 +181,74 @@ t_cose_mini_sign(const struct q_useful_buf_c payload, /* Don't actually have to create the Sig_structure fully in * memory. Just have to compute the hash of it. */ err = t_cose_crypto_hash_start(&hash_ctx, MINI_SIGN_HASH); + if(err != T_COSE_SUCCESS) { + goto Done; + } t_cose_crypto_hash_update(&hash_ctx, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(start_sig_struct)); t_cose_crypto_hash_update(&hash_ctx, payload_head); t_cose_crypto_hash_update(&hash_ctx, payload); err = t_cose_crypto_hash_finish(&hash_ctx, hash_output, &computed_hash); + if(err != T_COSE_SUCCESS) { + goto Done; + } - - const size_t required_len = payload.len + + /* ---- Size check ---- */ + /* Calculate the length of the output buffer required. It is + * just the payload plus a constant. This one check covers + * all the memcpy() calls below. + */ + const size_t required_len = sizeof(start_cose_sign1) + MAX_CBOR_HEAD + - sizeof(start_cose_sign1) + - sizeof(cose_sign1_sig_start); + payload.len + + sizeof(cose_sign1_sig_start) + + MINI_SIGN_SIG_LEN; if(output_buffer.len < required_len) { - return 0; + return T_COSE_ERR_TOO_SMALL; } - uint8_t *p; + /* ---- Output the COSE_Sign1 ---- */ + copy_ptr = output_buffer.ptr; - p = output_buffer.ptr; + memcpy(copy_ptr, start_cose_sign1, sizeof(start_cose_sign1)); + copy_ptr += sizeof(start_cose_sign1); - memcpy(p, start_cose_sign1, sizeof(start_cose_sign1)); - p += sizeof(start_cose_sign1); + memcpy(copy_ptr, payload_head.ptr, payload_head.len); + copy_ptr += payload_head.len; - memcpy(p, payload_head.ptr, payload_head.len); - p += payload_head.len; + memcpy(copy_ptr, payload.ptr, payload.len); + copy_ptr += payload.len; - memcpy(p, payload_head.ptr, payload.len); - p += payload.len; + memcpy(copy_ptr, cose_sign1_sig_start, sizeof(cose_sign1_sig_start)); + copy_ptr += sizeof(cose_sign1_sig_start); - memcpy(p, cose_sign1_sig_start, sizeof(cose_sign1_sig_start)); - p += payload.len; + const size_t u_len = (size_t)(copy_ptr - (uint8_t *)output_buffer.ptr); - struct q_useful_buf tmp2; - tmp2.len = p - (uint8_t *)output_buffer.ptr ; - tmp.ptr = p; + /* This won't go negative because of the check against required_len above + * so the cast is safe. + */ + signature_buffer.len = output_buffer.len - u_len; + signature_buffer.ptr = copy_ptr; - t_cose_crypto_sign(MINI_SIGN_ALG, - signing_key, - computed_hash, - tmp, - &signature); + + err = t_cose_crypto_sign(MINI_SIGN_ALG, + signing_key, + computed_hash, + signature_buffer, + &signature); output->ptr = output_buffer.ptr; - output->len = tmp2.len + MINI_SIGN_SIG_LEN; + output->len = u_len + signature.len; + /* I wrote this code without using UsefulBuf to save object code. + * It works and I saved object code, but I made about three + * mistakes with pointer math that I wouldn't have made + * with UsefulBuf that took a few hours of debugging to find. + */ - return 0; +Done: + return err; } - diff --git a/test/t_cose_austere_test.c b/test/t_cose_austere_test.c index 4984b185..14e26b19 100644 --- a/test/t_cose_austere_test.c +++ b/test/t_cose_austere_test.c @@ -1,10 +1,12 @@ -// -// t_cose_austere_test.c -// t_cose -// -// Created by Laurence Lundblade on 5/2/22. -// Copyright © 2022 Laurence Lundblade. All rights reserved. -// +/* +* t_cose_mini_sign_test.c +* +* Copyright 2022, Laurence Lundblade +* +* SPDX-License-Identifier: BSD-3-Clause +* +* See BSD-3-Clause license in README.md +*/ #include "t_cose_austere_test.h" #include "t_cose_make_test_pub_key.h" @@ -34,30 +36,39 @@ const uint8_t payload[] = { int32_t austere_test(void) { - enum t_cose_err_t err; - MakeUsefulBufOnStack(output, 250); - struct q_useful_buf_c cose_sign1; + enum t_cose_err_t err; + MakeUsefulBufOnStack( output, sizeof(payload) + T_COSE_MINI_SIGN_SIZE_OVERHEAD_ES256); + struct q_useful_buf_c cose_sign1; + struct t_cose_key key_pair; + struct t_cose_sign1_verify_ctx verify_ctx; + struct q_useful_buf_c verified_payload; - struct t_cose_key key_pair; - - err = make_ecdsa_key_pair(T_COSE_ALGORITHM_ES384, &key_pair); + err = make_ecdsa_key_pair(T_COSE_ALGORITHM_ES256, &key_pair); + if(err) { + return 10; + } err = t_cose_mini_sign(Q_USEFUL_BUF_FROM_BYTE_ARRAY_LITERAL(payload), - key_pair, - output, - &cose_sign1); - + key_pair, + output, + &cose_sign1); + if(err) { + return 20; + } - struct t_cose_sign1_verify_ctx verify_ctx; - t_cose_sign1_verify_init(&verify_ctx, 0); + t_cose_sign1_verify_init(&verify_ctx, 0); - t_cose_sign1_set_verification_key(&verify_ctx, key_pair); + t_cose_sign1_set_verification_key(&verify_ctx, key_pair); - struct q_useful_buf_c xx; - err = t_cose_sign1_verify(&verify_ctx, cose_sign1, - &xx, NULL); + err = t_cose_sign1_verify(&verify_ctx, cose_sign1, &verified_payload, NULL); + if(err) { + return 30; + } return 0; } + + +// TODO: test for output buffer too small From cd86857309bcb12e2a30de9fe780963bfeb4fe01 Mon Sep 17 00:00:00 2001 From: Laurence Lundblade Date: Tue, 18 Oct 2022 03:15:02 -0700 Subject: [PATCH 05/11] important bug fix and code tidiness --- inc/t_cose/t_cose_mini_sign.h | 17 +++-- inc/t_cose_austere_sign.h | 13 ---- src/t_cose_mini_sign.c | 63 +++++++++++------- t_cose.xcodeproj/project.pbxproj | 20 +++--- test/run_tests.c | 4 +- test/t_cose_austere_test.c | 74 --------------------- test/t_cose_austere_test.h | 17 ----- test/t_cose_mini_sign_test.c | 106 +++++++++++++++++++++++++++++++ test/t_cose_mini_sign_test.h | 21 ++++++ 9 files changed, 187 insertions(+), 148 deletions(-) delete mode 100644 inc/t_cose_austere_sign.h delete mode 100644 test/t_cose_austere_test.c delete mode 100644 test/t_cose_austere_test.h create mode 100644 test/t_cose_mini_sign_test.c create mode 100644 test/t_cose_mini_sign_test.h diff --git a/inc/t_cose/t_cose_mini_sign.h b/inc/t_cose/t_cose_mini_sign.h index 26067d4c..a2b45a5f 100644 --- a/inc/t_cose/t_cose_mini_sign.h +++ b/inc/t_cose/t_cose_mini_sign.h @@ -8,6 +8,8 @@ * See BSD-3-Clause license in README.md */ +// TODO: rename to mini_sign1 + #ifndef __T_COSE_MINI_SIGN_H__ #define __T_COSE_MINI_SIGN_H__ @@ -32,7 +34,7 @@ extern "C" { 3 + /* The CBOR head of the payload */ \ /* The payload -- add this in yourself */ \ 2 + /* CBOR head of signature */ \ - 64 // T_COSE_EC_P256_SIG_SIZE + 64 /* T_COSE_EC_P256_SIG_SIZE */ #define T_COSE_MINI_SIGN_SIZE_OVERHEAD_ES384 \ 1 + /* Open the array */ \ @@ -40,7 +42,7 @@ extern "C" { 3 + /* The CBOR head of the payload */ \ /* The payload -- add this in yourself */ \ 2 + /* CBOR head of signature */ \ - T_COSE_EC_P384_SIG_SIZE + 96 /* T_COSE_EC_P384_SIG_SIZE */ #define T_COSE_MINI_SIGN_SIZE_OVERHEAD_ES512 \ 1 + /* Open the array */ \ @@ -48,7 +50,7 @@ extern "C" { 3 + /* The CBOR head of the payload */ \ /* The payload -- add this in yourself */ \ 2 + /* CBOR head of signature */ \ - T_COSE_EC_P512_SIG_SIZE + 128 /* T_COSE_EC_P512_SIG_SIZE */ /* @@ -73,12 +75,9 @@ extern "C" { * This is roughly 500 bytes of object code versus 1,500 bytes for * t_cose_sign1_sign(). * - * One could modify the source to include fixed COSE header parameters - * or even a variable header parameter like the kid and the object - * code would still be small. I - * - * If modifications are made so the payload is fixed at compile time, - * the object code could be reduced. + * See comments in the source code for changing the algorithm that + * is supported, adding support for headers or reducing the object + * code even futher. */ enum t_cose_err_t t_cose_mini_sign(struct q_useful_buf_c payload, diff --git a/inc/t_cose_austere_sign.h b/inc/t_cose_austere_sign.h deleted file mode 100644 index 8a61b37f..00000000 --- a/inc/t_cose_austere_sign.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// t_cose_austere_sign.h -// t_cose -// -// Created by Laurence Lundblade on 5/2/22. -// Copyright © 2022 Laurence Lundblade. All rights reserved. -// - -#ifndef t_cose_austere_sign_h -#define t_cose_austere_sign_h - - -#endif /* t_cose_austere_sign_h */ diff --git a/src/t_cose_mini_sign.c b/src/t_cose_mini_sign.c index cca3d74d..f946b1b2 100644 --- a/src/t_cose_mini_sign.c +++ b/src/t_cose_mini_sign.c @@ -15,12 +15,24 @@ #include "qcbor/UsefulBuf.h" /* -Define one of these to configure the algorithm + * This could be modified to support other header parameters like the + * kid and the object code would still be bigger, but still very + * small. + * + * Or on the other hand, this could be modified to support only a + * fixed-size payload to make the object code even smaller. + */ + + +/* + * The algorithm is set at compile time for mini sign and can't be + * changed. Define one of these to configure the algorithm. #define T_COSE_MINI_SIGN_SELECT_ES256 #define T_COSE_MINI_SIGN_SELECT_ES384 #define T_COSE_MINI_SIGN_SELECT_ES512 */ + #define T_COSE_MINI_SIGN_SELECT_ES256 @@ -30,7 +42,7 @@ Define one of these to configure the algorithm #define MINI_SIGN_HASH_LEN T_COSE_CRYPTO_SHA256_SIZE #define MINI_SIGN_ALG T_COSE_ALGORITHM_ES256 #define MINI_SIGN_ALG_ID_BYTES 0x26 /* The literal byte that appears in the CBOR encoding */ -#define MINI_SIGN_SIG_LEN T_COSE_EC_P256_SIG_SIZE // Code below only works for lengths < 256 +#define MINI_SIGN_SIG_LEN T_COSE_EC_P256_SIG_SIZE #elif defined(T_COSE_MINI_SIGN_SELECT_ES384) @@ -38,7 +50,7 @@ Define one of these to configure the algorithm #define MINI_SIGN_HASH_LEN T_COSE_CRYPTO_SHA384_SIZE #define MINI_SIGN_ALG T_COSE_ALGORITHM_ES384 #define MINI_SIGN_ALG_ID_BYTES 0x38, 0x22 /* The literal byte that appears in the CBOR encoding */ -#define MINI_SIGN_SIG_LEN T_COSE_EC_P384_SIG_SIZE // Code below only works for lengths < 256 +#define MINI_SIGN_SIG_LEN T_COSE_EC_P384_SIG_SIZE #elif defined(T_COSE_MINI_SIGN_SELECT_ES512) @@ -46,7 +58,7 @@ Define one of these to configure the algorithm #define MINI_SIGN_HASH_LEN T_COSE_CRYPTO_SHA512_SIZE #define MINI_SIGN_ALG T_COSE_ALGORITHM_ES521 #define MINI_SIGN_ALG_ID_BYTES 0x38, 0x23 /* The literal byte that appears in the CBOR encoding */ -#define MINI_SIGN_SIG_LEN T_COSE_EC_P512_SIG_SIZE // Code below only works for lengths < 256 +#define MINI_SIGN_SIG_LEN T_COSE_EC_P512_SIG_SIZE #endif @@ -62,6 +74,7 @@ Define one of these to configure the algorithm 0xA1, 0x01, \ MINI_SIGN_ALG_ID_BYTES + /* * This is hard-coded bytes for the start of the CBOR for the following * CBOR that are the to-be-signed bytes. Hard coding like this saves @@ -75,7 +88,7 @@ Define one of these to configure the algorithm * payload : bstr * ] */ -static uint8_t start_sig_struct[] = { +static const uint8_t start_sig_struct[] = { 0x84, 0x6A,'S', 'i', 'g', 'n', 'a', 't', 'u', 'r', 'e', '1', PROT_HEADERS, // bstr wrapped protected header wtih algorithm ID @@ -85,7 +98,7 @@ static uint8_t start_sig_struct[] = { /* The first part of a COSE_Sign1: the opening array, * the protected parameters and the unproteced parameters. */ -static uint8_t start_cose_sign1[] = { +static const uint8_t start_cose_sign1[] = { 0x84, PROT_HEADERS, // bstr wrapped protected header wtih algorithm ID 0xa0, /* no unprotected headers, put some here if you want */ @@ -93,7 +106,7 @@ static uint8_t start_cose_sign1[] = { /* The Hard coded bytes for the CBOR head for the signature. It is less * code to hard code than to encode using encode_bstr_head() */ -static uint8_t cose_sign1_sig_start[] = { +static const uint8_t cose_sign1_sig_start[] = { 0x58, MINI_SIGN_SIG_LEN }; @@ -108,7 +121,7 @@ static uint8_t cose_sign1_sig_start[] = { /* - * @brief Encode a CBOR head for a byte string of given length + * @brief Encode a CBOR head for a byte string of given length. * * @param[in] len The length to encode. * @param[in] out_buffer Pointer and length to write to. @@ -117,30 +130,30 @@ static uint8_t cose_sign1_sig_start[] = { * or \c NULL_Q_USEFUL_BUF_C if @c len is * greater than 65355. * - * This is a scaled-down specific version of QCBOREncode_EncodeHead() + * This is a scaled-down version of QCBOREncode_EncodeHead() * in QCBOR. */ static inline struct q_useful_buf_c encode_bstr_head(const size_t len, const struct q_useful_buf out_buffer) { - uint8_t *bb = out_buffer.ptr; + uint8_t *out_buf = out_buffer.ptr; if(out_buffer.len < MAX_CBOR_HEAD) { return NULL_Q_USEFUL_BUF_C; } if(len < 24) { /* 24 is a special number in CBOR */ - bb[0] = 0x40 + (uint8_t)len; - return (struct q_useful_buf_c){bb, 1}; + out_buf[0] = 0x40 + (uint8_t)len; + return (struct q_useful_buf_c){out_buf, 1}; } else if(len < 256) { - bb[0] = 0x58; - bb[1] = (uint8_t)len; - return (struct q_useful_buf_c){bb, 2}; + out_buf[0] = 0x58; + out_buf[1] = (uint8_t)len; + return (struct q_useful_buf_c){out_buf, 2}; } else if(len < UINT16_MAX) { - bb[0] = 0x59; - bb[1] = (uint8_t)(len / 8); - bb[2] = (uint8_t)(len % 256); - return (struct q_useful_buf_c){bb, 3}; + out_buf[0] = 0x59; + out_buf[1] = (uint8_t)(len / 256); + out_buf[2] = (uint8_t)(len % 256); + return (struct q_useful_buf_c){out_buf, 3}; } else { return NULL_Q_USEFUL_BUF_C; } @@ -152,7 +165,7 @@ encode_bstr_head(const size_t len, const struct q_useful_buf out_buffer) */ enum t_cose_err_t t_cose_mini_sign(const struct q_useful_buf_c payload, - struct t_cose_key signing_key, + const struct t_cose_key signing_key, const struct q_useful_buf output_buffer, struct q_useful_buf_c *output) { @@ -244,9 +257,13 @@ t_cose_mini_sign(const struct q_useful_buf_c payload, output->len = u_len + signature.len; /* I wrote this code without using UsefulBuf to save object code. - * It works and I saved object code, but I made about three - * mistakes with pointer math that I wouldn't have made - * with UsefulBuf that took a few hours of debugging to find. + * It works and I saved object code, but I made about four + * mistakes with pointer math that I wouldn't have made with + * UsefulBuf that took a few hours of debugging to find. Or maybe + * I'm not as sharp as I used to be... + * + * Or said another way, this code doesn't have the same security / + * buffer level that QCBOR has, but it should be safe enough. */ Done: diff --git a/t_cose.xcodeproj/project.pbxproj b/t_cose.xcodeproj/project.pbxproj index bd4d0e72..c29827c3 100644 --- a/t_cose.xcodeproj/project.pbxproj +++ b/t_cose.xcodeproj/project.pbxproj @@ -63,9 +63,9 @@ E774835B28209B3200B352ED /* t_cose_mini_sign.c in Sources */ = {isa = PBXBuildFile; fileRef = E774835A28209B3200B352ED /* t_cose_mini_sign.c */; }; E774835C28209B3200B352ED /* t_cose_mini_sign.c in Sources */ = {isa = PBXBuildFile; fileRef = E774835A28209B3200B352ED /* t_cose_mini_sign.c */; }; E774835D28209B3200B352ED /* t_cose_mini_sign.c in Sources */ = {isa = PBXBuildFile; fileRef = E774835A28209B3200B352ED /* t_cose_mini_sign.c */; }; - E77483612820A94B00B352ED /* t_cose_austere_test.c in Sources */ = {isa = PBXBuildFile; fileRef = E77483602820A94B00B352ED /* t_cose_austere_test.c */; }; - E77483622820A94B00B352ED /* t_cose_austere_test.c in Sources */ = {isa = PBXBuildFile; fileRef = E77483602820A94B00B352ED /* t_cose_austere_test.c */; }; - E77483632820A94B00B352ED /* t_cose_austere_test.c in Sources */ = {isa = PBXBuildFile; fileRef = E77483602820A94B00B352ED /* t_cose_austere_test.c */; }; + E77483612820A94B00B352ED /* t_cose_mini_sign_test.c in Sources */ = {isa = PBXBuildFile; fileRef = E77483602820A94B00B352ED /* t_cose_mini_sign_test.c */; }; + E77483622820A94B00B352ED /* t_cose_mini_sign_test.c in Sources */ = {isa = PBXBuildFile; fileRef = E77483602820A94B00B352ED /* t_cose_mini_sign_test.c */; }; + E77483632820A94B00B352ED /* t_cose_mini_sign_test.c in Sources */ = {isa = PBXBuildFile; fileRef = E77483602820A94B00B352ED /* t_cose_mini_sign_test.c */; }; E7C960A627F7569E00FB537C /* libqcbor.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E7C960A527F7569500FB537C /* libqcbor.a */; }; E7C960A727F7569F00FB537C /* libqcbor.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E7C960A527F7569500FB537C /* libqcbor.a */; }; E7C960A827F756A000FB537C /* libqcbor.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E7C960A527F7569500FB537C /* libqcbor.a */; }; @@ -195,8 +195,8 @@ E772028523CAEC84006E966E /* t_cose_psa_noss */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = t_cose_psa_noss; sourceTree = BUILT_PRODUCTS_DIR; }; E774835A28209B3200B352ED /* t_cose_mini_sign.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = t_cose_mini_sign.c; sourceTree = ""; }; E774835E28209BC500B352ED /* t_cose_mini_sign.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = t_cose_mini_sign.h; path = t_cose/t_cose_mini_sign.h; sourceTree = ""; }; - E774835F2820A94B00B352ED /* t_cose_austere_test.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = t_cose_austere_test.h; sourceTree = ""; }; - E77483602820A94B00B352ED /* t_cose_austere_test.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = t_cose_austere_test.c; sourceTree = ""; }; + E774835F2820A94B00B352ED /* t_cose_mini_sign_test.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = t_cose_mini_sign_test.h; sourceTree = ""; }; + E77483602820A94B00B352ED /* t_cose_mini_sign_test.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = t_cose_mini_sign_test.c; sourceTree = ""; }; E7C960A527F7569500FB537C /* libqcbor.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libqcbor.a; path = ../../../../../usr/local/lib/libqcbor.a; sourceTree = ""; }; E7E36E78226CB8400040613B /* t_cose_openssl */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = t_cose_openssl; sourceTree = BUILT_PRODUCTS_DIR; }; E7E36E7B226CB8400040613B /* main.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = main.c; sourceTree = ""; }; @@ -415,8 +415,8 @@ E721CB9723628E0B00C7FD56 /* t_cose_make_test_pub_key.h */, E721CB9823628E9E00C7FD56 /* t_cose_make_openssl_test_key.c */, E721CB9123628B5F00C7FD56 /* t_cose_make_psa_test_key.c */, - E774835F2820A94B00B352ED /* t_cose_austere_test.h */, - E77483602820A94B00B352ED /* t_cose_austere_test.c */, + E774835F2820A94B00B352ED /* t_cose_mini_sign_test.h */, + E77483602820A94B00B352ED /* t_cose_mini_sign_test.c */, ); path = test; sourceTree = ""; @@ -578,7 +578,7 @@ E774835B28209B3200B352ED /* t_cose_mini_sign.c in Sources */, E730E61623612DAB00175CE0 /* t_cose_test.c in Sources */, E730E61823612DAB00175CE0 /* main.c in Sources */, - E77483612820A94B00B352ED /* t_cose_austere_test.c in Sources */, + E77483612820A94B00B352ED /* t_cose_mini_sign_test.c in Sources */, E730E61923612DAB00175CE0 /* t_cose_sign1_sign.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -626,7 +626,7 @@ E73CDABC23A7316700D262E0 /* t_cose_make_test_messages.c in Sources */, E73CDABD23A7316700D262E0 /* main.c in Sources */, E73CDABE23A7316700D262E0 /* run_tests.c in Sources */, - E77483632820A94B00B352ED /* t_cose_austere_test.c in Sources */, + E77483632820A94B00B352ED /* t_cose_mini_sign_test.c in Sources */, E73CDABF23A7316700D262E0 /* t_cose_sign1_sign.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -658,7 +658,7 @@ E72FB01D231ADAA8000970FE /* run_tests.c in Sources */, E721CB9A2362ABA400C7FD56 /* t_cose_make_openssl_test_key.c in Sources */, E7E36EA5226CBB570040613B /* t_cose_openssl_crypto.c in Sources */, - E77483622820A94B00B352ED /* t_cose_austere_test.c in Sources */, + E77483622820A94B00B352ED /* t_cose_mini_sign_test.c in Sources */, 0F91057A2321878F00008572 /* t_cose_parameters.c in Sources */, 0F8B2FEF2345A33A00A22349 /* t_cose_make_test_messages.c in Sources */, E7E36E90226CB9460040613B /* t_cose_util.c in Sources */, diff --git a/test/run_tests.c b/test/run_tests.c index 3b0f5a41..ef42ef14 100644 --- a/test/run_tests.c +++ b/test/run_tests.c @@ -17,7 +17,7 @@ #include "t_cose_test.h" #include "t_cose_sign_verify_test.h" -#include "t_cose_austere_test.h" +#include "t_cose_mini_sign_test.h" /* @@ -63,7 +63,7 @@ static test_entry s_tests[] = { TEST_ENTRY(sign_verify_sig_fail_test), TEST_ENTRY(sign_verify_get_size_test), TEST_ENTRY(known_good_test), - TEST_ENTRY(austere_test), + TEST_ENTRY(mini_sign_test), #endif /* T_COSE_DISABLE_SIGN_VERIFY_TESTS */ #ifndef T_COSE_DISABLE_SHORT_CIRCUIT_SIGN diff --git a/test/t_cose_austere_test.c b/test/t_cose_austere_test.c deleted file mode 100644 index 14e26b19..00000000 --- a/test/t_cose_austere_test.c +++ /dev/null @@ -1,74 +0,0 @@ -/* -* t_cose_mini_sign_test.c -* -* Copyright 2022, Laurence Lundblade -* -* SPDX-License-Identifier: BSD-3-Clause -* -* See BSD-3-Clause license in README.md -*/ - -#include "t_cose_austere_test.h" -#include "t_cose_make_test_pub_key.h" - -#include "t_cose/t_cose_mini_sign.h" -#include "t_cose/t_cose_sign1_verify.h" - -const uint8_t payload[] = { - 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, - 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, - 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, - 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, - 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, - 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, - 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, - 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, - 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, - 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, - 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, - 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, - 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, - 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, - 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, - 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03 -}; - - -int32_t austere_test(void) { - - enum t_cose_err_t err; - MakeUsefulBufOnStack( output, sizeof(payload) + T_COSE_MINI_SIGN_SIZE_OVERHEAD_ES256); - struct q_useful_buf_c cose_sign1; - struct t_cose_key key_pair; - struct t_cose_sign1_verify_ctx verify_ctx; - struct q_useful_buf_c verified_payload; - - - err = make_ecdsa_key_pair(T_COSE_ALGORITHM_ES256, &key_pair); - if(err) { - return 10; - } - - err = t_cose_mini_sign(Q_USEFUL_BUF_FROM_BYTE_ARRAY_LITERAL(payload), - key_pair, - output, - &cose_sign1); - if(err) { - return 20; - } - - - t_cose_sign1_verify_init(&verify_ctx, 0); - - t_cose_sign1_set_verification_key(&verify_ctx, key_pair); - - err = t_cose_sign1_verify(&verify_ctx, cose_sign1, &verified_payload, NULL); - if(err) { - return 30; - } - - return 0; -} - - -// TODO: test for output buffer too small diff --git a/test/t_cose_austere_test.h b/test/t_cose_austere_test.h deleted file mode 100644 index 52ba1a9c..00000000 --- a/test/t_cose_austere_test.h +++ /dev/null @@ -1,17 +0,0 @@ -// -// t_cose_austere_test.h -// t_cose -// -// Created by Laurence Lundblade on 5/2/22. -// Copyright © 2022 Laurence Lundblade. All rights reserved. -// - -#ifndef t_cose_austere_test_h -#define t_cose_austere_test_h - - -#include - -int32_t austere_test(void); - -#endif /* t_cose_austere_test_h */ diff --git a/test/t_cose_mini_sign_test.c b/test/t_cose_mini_sign_test.c new file mode 100644 index 00000000..95337b69 --- /dev/null +++ b/test/t_cose_mini_sign_test.c @@ -0,0 +1,106 @@ +/* + * t_cose_mini_sign_test.c + * + * Copyright 2022, Laurence Lundblade + * + * SPDX-License-Identifier: BSD-3-Clause + * + * See BSD-3-Clause license in README.md + */ + +#include "t_cose_mini_sign_test.h" +#include "t_cose_make_test_pub_key.h" + +#include "t_cose/t_cose_mini_sign.h" +#include "t_cose/t_cose_sign1_verify.h" + +static const uint8_t payload[] = { + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03 +}; + + +int32_t mini_sign_test(void) { + + enum t_cose_err_t err; + MakeUsefulBufOnStack( output, sizeof(payload) + T_COSE_MINI_SIGN_SIZE_OVERHEAD_ES256); + struct q_useful_buf_c cose_sign1; + struct t_cose_key key_pair; + struct t_cose_sign1_verify_ctx verify_ctx; + struct q_useful_buf_c verified_payload; + + + err = make_ecdsa_key_pair(T_COSE_ALGORITHM_ES256, &key_pair); + if(err) { + return 10; + } + + err = t_cose_mini_sign(Q_USEFUL_BUF_FROM_BYTE_ARRAY_LITERAL(payload), + key_pair, + output, + &cose_sign1); + if(err) { + return 20; + } + + + t_cose_sign1_verify_init(&verify_ctx, 0); + + t_cose_sign1_set_verification_key(&verify_ctx, key_pair); + + err = t_cose_sign1_verify(&verify_ctx, cose_sign1, &verified_payload, NULL); + if(err) { + return 30; + } + + return 0; +} + + +// TODO: test for output buffer too small diff --git a/test/t_cose_mini_sign_test.h b/test/t_cose_mini_sign_test.h new file mode 100644 index 00000000..60017b50 --- /dev/null +++ b/test/t_cose_mini_sign_test.h @@ -0,0 +1,21 @@ +/* + * t_cose_mini_sign_test.h + * + * Copyright 2022, Laurence Lundblade + * Created by Laurence Lundblade on 5/2/22. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * See BSD-3-Clause license in README.md + */ + + +#ifndef t_cose_mini_sign_test_h +#define t_cose_mini_sign_test_h + + +#include + +int32_t mini_sign_test(void); + +#endif /* t_cose_mini_sign_test_h */ From e68ab886abe6a959e2ac020d0f9ef8851c47cc77 Mon Sep 17 00:00:00 2001 From: Laurence Lundblade Date: Tue, 18 Oct 2022 23:46:26 -0700 Subject: [PATCH 06/11] rename to t_cose_mini_sign1_sign --- Makefile.ossl | 4 +- ...e_mini_sign.h => t_cose_mini_sign1_sign.h} | 5 +-- ...e_mini_sign.c => t_cose_mini_sign1_sign.c} | 12 +++--- t_cose.xcodeproj/project.pbxproj | 40 +++++++++---------- test/run_tests.c | 4 +- ...n_test.c => t_cose_mini_sign1_sign_test.c} | 10 ++--- ...n_test.h => t_cose_mini_sign1_sign_test.h} | 2 +- 7 files changed, 38 insertions(+), 39 deletions(-) rename inc/t_cose/{t_cose_mini_sign.h => t_cose_mini_sign1_sign.h} (96%) rename src/{t_cose_mini_sign.c => t_cose_mini_sign1_sign.c} (96%) rename test/{t_cose_mini_sign_test.c => t_cose_mini_sign1_sign_test.c} (93%) rename test/{t_cose_mini_sign_test.h => t_cose_mini_sign1_sign_test.h} (90%) diff --git a/Makefile.ossl b/Makefile.ossl index 6c3dac93..f3e6b098 100644 --- a/Makefile.ossl +++ b/Makefile.ossl @@ -54,7 +54,7 @@ C_OPTS=-Os -fPIC # ---- T_COSE Config and test options ---- TEST_CONFIG_OPTS= -TEST_OBJ=test/t_cose_test.o test/run_tests.o test/t_cose_sign_verify_test.o test/t_cose_make_test_messages.o test/t_cose_mini_sign_test.o $(CRYPTO_TEST_OBJ) +TEST_OBJ=test/t_cose_test.o test/run_tests.o test/t_cose_sign_verify_test.o test/t_cose_make_test_messages.o test/t_cose_mini_sign1_sign_test.o $(CRYPTO_TEST_OBJ) # ---- the main body that is invariant ---- @@ -62,7 +62,7 @@ INC=-I inc -I test -I src ALL_INC=$(INC) $(CRYPTO_INC) $(QCBOR_INC) CFLAGS=$(CMD_LINE) $(ALL_INC) $(C_OPTS) $(TEST_CONFIG_OPTS) $(CRYPTO_CONFIG_OPTS) -SRC_OBJ=src/t_cose_sign1_verify.o src/t_cose_sign1_sign.o src/t_cose_mini_sign.o src/t_cose_util.o src/t_cose_parameters.o src/t_cose_short_circuit.o +SRC_OBJ=src/t_cose_sign1_verify.o src/t_cose_sign1_sign.o src/t_cose_mini_sign1_sign.o src/t_cose_util.o src/t_cose_parameters.o src/t_cose_short_circuit.o .PHONY: all install install_headers install_so uninstall clean diff --git a/inc/t_cose/t_cose_mini_sign.h b/inc/t_cose/t_cose_mini_sign1_sign.h similarity index 96% rename from inc/t_cose/t_cose_mini_sign.h rename to inc/t_cose/t_cose_mini_sign1_sign.h index a2b45a5f..f669d33b 100644 --- a/inc/t_cose/t_cose_mini_sign.h +++ b/inc/t_cose/t_cose_mini_sign1_sign.h @@ -1,5 +1,5 @@ /* - * t_cose_mini_sign.h + * t_cose_mini_sign1_sign.h * * Copyright 2022, Laurence Lundblade * @@ -8,7 +8,6 @@ * See BSD-3-Clause license in README.md */ -// TODO: rename to mini_sign1 #ifndef __T_COSE_MINI_SIGN_H__ #define __T_COSE_MINI_SIGN_H__ @@ -80,7 +79,7 @@ extern "C" { * code even futher. */ enum t_cose_err_t -t_cose_mini_sign(struct q_useful_buf_c payload, +t_cose_mini_sign1_sign(struct q_useful_buf_c payload, struct t_cose_key signing_key, struct q_useful_buf output_buffer, struct q_useful_buf_c *output); diff --git a/src/t_cose_mini_sign.c b/src/t_cose_mini_sign1_sign.c similarity index 96% rename from src/t_cose_mini_sign.c rename to src/t_cose_mini_sign1_sign.c index f946b1b2..caf3a32b 100644 --- a/src/t_cose_mini_sign.c +++ b/src/t_cose_mini_sign1_sign.c @@ -1,5 +1,5 @@ /* - * t_cose_mini_sign.c + * t_cose_mini_sign1_sign.c * * Copyright 2022, Laurence Lundblade * @@ -8,7 +8,7 @@ * See BSD-3-Clause license in README.md */ -#include "t_cose/t_cose_mini_sign.h" +#include "t_cose/t_cose_mini_sign1_sign.h" #include "t_cose/t_cose_common.h" #include "t_cose_crypto.h" @@ -164,10 +164,10 @@ encode_bstr_head(const size_t len, const struct q_useful_buf out_buffer) * Public function. */ enum t_cose_err_t -t_cose_mini_sign(const struct q_useful_buf_c payload, - const struct t_cose_key signing_key, - const struct q_useful_buf output_buffer, - struct q_useful_buf_c *output) +t_cose_mini_sign1_sign(const struct q_useful_buf_c payload, + const struct t_cose_key signing_key, + const struct q_useful_buf output_buffer, + struct q_useful_buf_c *output) { struct t_cose_crypto_hash hash_ctx; enum t_cose_err_t err; diff --git a/t_cose.xcodeproj/project.pbxproj b/t_cose.xcodeproj/project.pbxproj index a3c61bed..bd6d0e3a 100644 --- a/t_cose.xcodeproj/project.pbxproj +++ b/t_cose.xcodeproj/project.pbxproj @@ -63,12 +63,12 @@ E772027C23CAEC84006E966E /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = E7E36E7B226CB8400040613B /* main.c */; }; E772027D23CAEC84006E966E /* run_tests.c in Sources */ = {isa = PBXBuildFile; fileRef = E72FB01C231ADAA8000970FE /* run_tests.c */; }; E772027E23CAEC84006E966E /* t_cose_sign1_sign.c in Sources */ = {isa = PBXBuildFile; fileRef = E7E36E8E226CB9460040613B /* t_cose_sign1_sign.c */; }; - E774835B28209B3200B352ED /* t_cose_mini_sign.c in Sources */ = {isa = PBXBuildFile; fileRef = E774835A28209B3200B352ED /* t_cose_mini_sign.c */; }; - E774835C28209B3200B352ED /* t_cose_mini_sign.c in Sources */ = {isa = PBXBuildFile; fileRef = E774835A28209B3200B352ED /* t_cose_mini_sign.c */; }; - E774835D28209B3200B352ED /* t_cose_mini_sign.c in Sources */ = {isa = PBXBuildFile; fileRef = E774835A28209B3200B352ED /* t_cose_mini_sign.c */; }; - E77483612820A94B00B352ED /* t_cose_mini_sign_test.c in Sources */ = {isa = PBXBuildFile; fileRef = E77483602820A94B00B352ED /* t_cose_mini_sign_test.c */; }; - E77483622820A94B00B352ED /* t_cose_mini_sign_test.c in Sources */ = {isa = PBXBuildFile; fileRef = E77483602820A94B00B352ED /* t_cose_mini_sign_test.c */; }; - E77483632820A94B00B352ED /* t_cose_mini_sign_test.c in Sources */ = {isa = PBXBuildFile; fileRef = E77483602820A94B00B352ED /* t_cose_mini_sign_test.c */; }; + E774835B28209B3200B352ED /* t_cose_mini_sign1_sign.c in Sources */ = {isa = PBXBuildFile; fileRef = E774835A28209B3200B352ED /* t_cose_mini_sign1_sign.c */; }; + E774835C28209B3200B352ED /* t_cose_mini_sign1_sign.c in Sources */ = {isa = PBXBuildFile; fileRef = E774835A28209B3200B352ED /* t_cose_mini_sign1_sign.c */; }; + E774835D28209B3200B352ED /* t_cose_mini_sign1_sign.c in Sources */ = {isa = PBXBuildFile; fileRef = E774835A28209B3200B352ED /* t_cose_mini_sign1_sign.c */; }; + E77483612820A94B00B352ED /* t_cose_mini_sign1_sign_test.c in Sources */ = {isa = PBXBuildFile; fileRef = E77483602820A94B00B352ED /* t_cose_mini_sign1_sign_test.c */; }; + E77483622820A94B00B352ED /* t_cose_mini_sign1_sign_test.c in Sources */ = {isa = PBXBuildFile; fileRef = E77483602820A94B00B352ED /* t_cose_mini_sign1_sign_test.c */; }; + E77483632820A94B00B352ED /* t_cose_mini_sign1_sign_test.c in Sources */ = {isa = PBXBuildFile; fileRef = E77483602820A94B00B352ED /* t_cose_mini_sign1_sign_test.c */; }; E7C960A627F7569E00FB537C /* libqcbor.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E7C960A527F7569500FB537C /* libqcbor.a */; }; E7C960A727F7569F00FB537C /* libqcbor.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E7C960A527F7569500FB537C /* libqcbor.a */; }; E7C960A827F756A000FB537C /* libqcbor.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E7C960A527F7569500FB537C /* libqcbor.a */; }; @@ -198,10 +198,10 @@ E751F9EE27E1F85000EBA5FA /* crypto_values.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = crypto_values.h; path = ../../../../../usr/local/include/psa/crypto_values.h; sourceTree = ""; }; E751F9F027E1F90F00EBA5FA /* libmbedcrypto.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmbedcrypto.a; path = ../../../../../usr/local/lib/libmbedcrypto.a; sourceTree = ""; }; E772028523CAEC84006E966E /* t_cose_psa_noss */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = t_cose_psa_noss; sourceTree = BUILT_PRODUCTS_DIR; }; - E774835A28209B3200B352ED /* t_cose_mini_sign.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = t_cose_mini_sign.c; sourceTree = ""; }; - E774835E28209BC500B352ED /* t_cose_mini_sign.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = t_cose_mini_sign.h; path = t_cose/t_cose_mini_sign.h; sourceTree = ""; }; - E774835F2820A94B00B352ED /* t_cose_mini_sign_test.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = t_cose_mini_sign_test.h; sourceTree = ""; }; - E77483602820A94B00B352ED /* t_cose_mini_sign_test.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = t_cose_mini_sign_test.c; sourceTree = ""; }; + E774835A28209B3200B352ED /* t_cose_mini_sign1_sign.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = t_cose_mini_sign1_sign.c; sourceTree = ""; }; + E774835E28209BC500B352ED /* t_cose_mini_sign1_sign.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = t_cose_mini_sign1_sign.h; path = t_cose/t_cose_mini_sign1_sign.h; sourceTree = ""; }; + E774835F2820A94B00B352ED /* t_cose_mini_sign1_sign_test.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = t_cose_mini_sign1_sign_test.h; sourceTree = ""; }; + E77483602820A94B00B352ED /* t_cose_mini_sign1_sign_test.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = t_cose_mini_sign1_sign_test.c; sourceTree = ""; }; E7C960A527F7569500FB537C /* libqcbor.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libqcbor.a; path = ../../../../../usr/local/lib/libqcbor.a; sourceTree = ""; }; E7E36E78226CB8400040613B /* t_cose_openssl */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = t_cose_openssl; sourceTree = BUILT_PRODUCTS_DIR; }; E7E36E7B226CB8400040613B /* main.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = main.c; sourceTree = ""; }; @@ -351,7 +351,7 @@ E7E36E82226CB9460040613B /* inc */ = { isa = PBXGroup; children = ( - E774835E28209BC500B352ED /* t_cose_mini_sign.h */, + E774835E28209BC500B352ED /* t_cose_mini_sign1_sign.h */, E72EC9EF242E74EE006D3DD3 /* q_useful_buf.h */, E72EC9ED242E74EE006D3DD3 /* t_cose_common.h */, E72EC9EC242E74EE006D3DD3 /* t_cose_sign1_sign.h */, @@ -373,7 +373,7 @@ E7E36E8C226CB9460040613B /* t_cose_util.h */, E7E36E8D226CB9460040613B /* t_cose_crypto.h */, E7E36E8E226CB9460040613B /* t_cose_sign1_sign.c */, - E774835A28209B3200B352ED /* t_cose_mini_sign.c */, + E774835A28209B3200B352ED /* t_cose_mini_sign1_sign.c */, ); path = src; sourceTree = ""; @@ -422,8 +422,8 @@ E721CB9723628E0B00C7FD56 /* t_cose_make_test_pub_key.h */, E721CB9823628E9E00C7FD56 /* t_cose_make_openssl_test_key.c */, E721CB9123628B5F00C7FD56 /* t_cose_make_psa_test_key.c */, - E774835F2820A94B00B352ED /* t_cose_mini_sign_test.h */, - E77483602820A94B00B352ED /* t_cose_mini_sign_test.c */, + E774835F2820A94B00B352ED /* t_cose_mini_sign1_sign_test.h */, + E77483602820A94B00B352ED /* t_cose_mini_sign1_sign_test.c */, ); path = test; sourceTree = ""; @@ -583,10 +583,10 @@ E730E61223612DAB00175CE0 /* t_cose_make_test_messages.c in Sources */, E730E61323612DAB00175CE0 /* t_cose_util.c in Sources */, E730E61523612DAB00175CE0 /* sha256.c in Sources */, - E774835B28209B3200B352ED /* t_cose_mini_sign.c in Sources */, + E774835B28209B3200B352ED /* t_cose_mini_sign1_sign.c in Sources */, E730E61623612DAB00175CE0 /* t_cose_test.c in Sources */, E730E61823612DAB00175CE0 /* main.c in Sources */, - E77483612820A94B00B352ED /* t_cose_mini_sign_test.c in Sources */, + E77483612820A94B00B352ED /* t_cose_mini_sign1_sign_test.c in Sources */, E730E61923612DAB00175CE0 /* t_cose_sign1_sign.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -624,7 +624,7 @@ files = ( E73CDAAE23A7316700D262E0 /* t_cose_sign1_verify.c in Sources */, E73CDAB023A7316700D262E0 /* t_cose_test.c in Sources */, - E774835D28209B3200B352ED /* t_cose_mini_sign.c in Sources */, + E774835D28209B3200B352ED /* t_cose_mini_sign1_sign.c in Sources */, E73CDAD423AD4F3900D262E0 /* t_cose_psa_crypto.c in Sources */, E73FDFC728B6BB63002CF0CC /* t_cose_short_circuit.c in Sources */, E73CDAB223A7316700D262E0 /* t_cose_util.c in Sources */, @@ -635,7 +635,7 @@ E73CDABC23A7316700D262E0 /* t_cose_make_test_messages.c in Sources */, E73CDABD23A7316700D262E0 /* main.c in Sources */, E73CDABE23A7316700D262E0 /* run_tests.c in Sources */, - E77483632820A94B00B352ED /* t_cose_mini_sign_test.c in Sources */, + E77483632820A94B00B352ED /* t_cose_mini_sign1_sign_test.c in Sources */, E73CDABF23A7316700D262E0 /* t_cose_sign1_sign.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -667,12 +667,12 @@ E72FB01D231ADAA8000970FE /* run_tests.c in Sources */, E721CB9A2362ABA400C7FD56 /* t_cose_make_openssl_test_key.c in Sources */, E7E36EA5226CBB570040613B /* t_cose_openssl_crypto.c in Sources */, - E77483622820A94B00B352ED /* t_cose_mini_sign_test.c in Sources */, + E77483622820A94B00B352ED /* t_cose_mini_sign1_sign_test.c in Sources */, 0F91057A2321878F00008572 /* t_cose_parameters.c in Sources */, E73FDFC628B6BB62002CF0CC /* t_cose_short_circuit.c in Sources */, 0F8B2FEF2345A33A00A22349 /* t_cose_make_test_messages.c in Sources */, E7E36E90226CB9460040613B /* t_cose_util.c in Sources */, - E774835C28209B3200B352ED /* t_cose_mini_sign.c in Sources */, + E774835C28209B3200B352ED /* t_cose_mini_sign1_sign.c in Sources */, E721CB9B2362AC2A00C7FD56 /* t_cose_sign_verify_test.c in Sources */, E7F70AC62270DFAE007CE07F /* t_cose_test.c in Sources */, E7E36E7C226CB8400040613B /* main.c in Sources */, diff --git a/test/run_tests.c b/test/run_tests.c index b2ca9178..4e52ac88 100644 --- a/test/run_tests.c +++ b/test/run_tests.c @@ -17,7 +17,7 @@ #include "t_cose_test.h" #include "t_cose_sign_verify_test.h" -#include "t_cose_mini_sign_test.h" +#include "t_cose_mini_sign1_sign_test.h" /* @@ -62,7 +62,7 @@ static test_entry s_tests[] = { TEST_ENTRY(sign_verify_make_cwt_test), TEST_ENTRY(sign_verify_sig_fail_test), TEST_ENTRY(sign_verify_get_size_test), - TEST_ENTRY(mini_sign_test), + TEST_ENTRY(mini_sign1_sign_test), TEST_ENTRY(sign_verify_known_good_test), TEST_ENTRY(sign_verify_unsupported_test), TEST_ENTRY(sign_verify_bad_auxiliary_buffer), diff --git a/test/t_cose_mini_sign_test.c b/test/t_cose_mini_sign1_sign_test.c similarity index 93% rename from test/t_cose_mini_sign_test.c rename to test/t_cose_mini_sign1_sign_test.c index 60f906e6..731f23c8 100644 --- a/test/t_cose_mini_sign_test.c +++ b/test/t_cose_mini_sign1_sign_test.c @@ -1,5 +1,5 @@ /* - * t_cose_mini_sign_test.c + * t_cose_mini_sign1_sign_test.c * * Copyright 2022, Laurence Lundblade * @@ -8,10 +8,10 @@ * See BSD-3-Clause license in README.md */ -#include "t_cose_mini_sign_test.h" +#include "t_cose_mini_sign1_sign_test.h" #include "t_cose_make_test_pub_key.h" -#include "t_cose/t_cose_mini_sign.h" +#include "t_cose/t_cose_mini_sign1_sign.h" #include "t_cose/t_cose_sign1_verify.h" static const uint8_t payload[] = { @@ -66,7 +66,7 @@ static const uint8_t payload[] = { }; -int32_t mini_sign_test(void) { +int32_t mini_sign1_sign_test(void) { enum t_cose_err_t err; MakeUsefulBufOnStack( output, sizeof(payload) + T_COSE_MINI_SIGN_SIZE_OVERHEAD_ES256); @@ -81,7 +81,7 @@ int32_t mini_sign_test(void) { return 10; } - err = t_cose_mini_sign(Q_USEFUL_BUF_FROM_BYTE_ARRAY_LITERAL(payload), + err = t_cose_mini_sign1_sign(Q_USEFUL_BUF_FROM_BYTE_ARRAY_LITERAL(payload), key_pair, output, &cose_sign1); diff --git a/test/t_cose_mini_sign_test.h b/test/t_cose_mini_sign1_sign_test.h similarity index 90% rename from test/t_cose_mini_sign_test.h rename to test/t_cose_mini_sign1_sign_test.h index 60017b50..0b58ea63 100644 --- a/test/t_cose_mini_sign_test.h +++ b/test/t_cose_mini_sign1_sign_test.h @@ -16,6 +16,6 @@ #include -int32_t mini_sign_test(void); +int32_t mini_sign1_sign_test(void); #endif /* t_cose_mini_sign_test_h */ From 4d2fbffd96b118ec095a3867e57112c6560acd42 Mon Sep 17 00:00:00 2001 From: Laurence Lundblade Date: Wed, 19 Oct 2022 00:03:35 -0700 Subject: [PATCH 07/11] Documentation improvements --- inc/t_cose/t_cose_mini_sign1_sign.h | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/inc/t_cose/t_cose_mini_sign1_sign.h b/inc/t_cose/t_cose_mini_sign1_sign.h index f669d33b..10187bfc 100644 --- a/inc/t_cose/t_cose_mini_sign1_sign.h +++ b/inc/t_cose/t_cose_mini_sign1_sign.h @@ -52,7 +52,7 @@ extern "C" { 128 /* T_COSE_EC_P512_SIG_SIZE */ -/* +/** * @brief Create a COSE_Sign1 with fixed algorithm and no header parameters. * * @param[in] payload The payload to sign. @@ -74,15 +74,31 @@ extern "C" { * This is roughly 500 bytes of object code versus 1,500 bytes for * t_cose_sign1_sign(). * + * Even if you don't need small object code, this is + * a super easy to use COSE Sign1 API if ES256 is good enough + * and you don't need any other header parameters. + * + * See \ref T_COSE_MINI_SIGN_SIZE_OVERHEAD_ES256 for a compile time + * constant that gives the size over and above the payload size + * for the output buffer. If \ref output_buffer is too small + * an error will be returned. + * + * This works with either OpenSSL and PSA Crypto (MbedTLS). It + * is less object code with PSA Crypto. + * + * ES384 and ES512 are also supported, but you have to modify + * the source to switch to one of them. The source could be + * further modified to support RSA. + * * See comments in the source code for changing the algorithm that * is supported, adding support for headers or reducing the object * code even futher. */ enum t_cose_err_t t_cose_mini_sign1_sign(struct q_useful_buf_c payload, - struct t_cose_key signing_key, - struct q_useful_buf output_buffer, - struct q_useful_buf_c *output); + struct t_cose_key signing_key, + struct q_useful_buf output_buffer, + struct q_useful_buf_c *output); #ifdef __cplusplus From fa052f7f16536969c3c6ea7dcab185a6376ef1f2 Mon Sep 17 00:00:00 2001 From: Laurence Lundblade Date: Sun, 25 Jun 2023 03:02:39 -0700 Subject: [PATCH 08/11] Improve test coverage and a few fixes --- inc/t_cose/t_cose_mini_sign1_sign.h | 10 +++--- src/t_cose_mini_sign1_sign.c | 11 +++++-- test/t_cose_mini_sign1_sign_test.c | 50 +++++++++++++++++++++++++---- 3 files changed, 58 insertions(+), 13 deletions(-) diff --git a/inc/t_cose/t_cose_mini_sign1_sign.h b/inc/t_cose/t_cose_mini_sign1_sign.h index 10187bfc..1c33517f 100644 --- a/inc/t_cose/t_cose_mini_sign1_sign.h +++ b/inc/t_cose/t_cose_mini_sign1_sign.h @@ -1,7 +1,7 @@ /* * t_cose_mini_sign1_sign.h * - * Copyright 2022, Laurence Lundblade + * Copyright 2022-2023, Laurence Lundblade * * SPDX-License-Identifier: BSD-3-Clause * @@ -71,9 +71,6 @@ extern "C" { * any header parameter except the algorithm ID. There is also * a maximum size of the payload at UINT16_MAX. * - * This is roughly 500 bytes of object code versus 1,500 bytes for - * t_cose_sign1_sign(). - * * Even if you don't need small object code, this is * a super easy to use COSE Sign1 API if ES256 is good enough * and you don't need any other header parameters. @@ -83,8 +80,11 @@ extern "C" { * for the output buffer. If \ref output_buffer is too small * an error will be returned. * + * The object code size is about 500 bytes plus the crypto library. * This works with either OpenSSL and PSA Crypto (MbedTLS). It - * is less object code with PSA Crypto. + * is less total object code with PSA Crypto. This contrasts + * with about 1500 bytes plus QCBOR plus the crypto library + * for t_cose_sign1_sign(). * * ES384 and ES512 are also supported, but you have to modify * the source to switch to one of them. The source could be diff --git a/src/t_cose_mini_sign1_sign.c b/src/t_cose_mini_sign1_sign.c index caf3a32b..624f6f27 100644 --- a/src/t_cose_mini_sign1_sign.c +++ b/src/t_cose_mini_sign1_sign.c @@ -33,7 +33,11 @@ #define T_COSE_MINI_SIGN_SELECT_ES512 */ +#if !defined(T_COSE_MINI_SIGN_SELECT_ES256) && \ + !defined(T_COSE_MINI_SIGN_SELECT_ES384) && \ + !defined(T_COSE_MINI_SIGN_SELECT_ES512) #define T_COSE_MINI_SIGN_SELECT_ES256 +#endif #if defined(T_COSE_MINI_SIGN_SELECT_ES256) @@ -184,7 +188,7 @@ t_cose_mini_sign1_sign(const struct q_useful_buf_c payload, if(payload_head.ptr == NULL) { /* The payload is too large (the only reason encode_bstr_head() - * errors out. + * errors out). */ return T_COSE_ERR_TOO_LONG; } @@ -263,7 +267,10 @@ t_cose_mini_sign1_sign(const struct q_useful_buf_c payload, * I'm not as sharp as I used to be... * * Or said another way, this code doesn't have the same security / - * buffer level that QCBOR has, but it should be safe enough. + * buffer level that QCBOR has. It hasn't gone through the same + * security review and static analysis and such yet either. In + * theory it is safe, but I'd advise you review and analyze + * before security-critical use. */ Done: diff --git a/test/t_cose_mini_sign1_sign_test.c b/test/t_cose_mini_sign1_sign_test.c index 731f23c8..5f2f2894 100644 --- a/test/t_cose_mini_sign1_sign_test.c +++ b/test/t_cose_mini_sign1_sign_test.c @@ -69,22 +69,25 @@ static const uint8_t payload[] = { int32_t mini_sign1_sign_test(void) { enum t_cose_err_t err; - MakeUsefulBufOnStack( output, sizeof(payload) + T_COSE_MINI_SIGN_SIZE_OVERHEAD_ES256); + MakeUsefulBufOnStack( out_buffer, sizeof(payload) + T_COSE_MINI_SIGN_SIZE_OVERHEAD_ES512); struct q_useful_buf_c cose_sign1; struct t_cose_key key_pair; struct t_cose_sign1_verify_ctx verify_ctx; struct q_useful_buf_c verified_payload; + // TODO: tests for different algorithms + // How to do this with compiled-in algorithm? err = make_key_pair(T_COSE_ALGORITHM_ES256, &key_pair); if(err) { return 10; } + /* The main happy-path test */ err = t_cose_mini_sign1_sign(Q_USEFUL_BUF_FROM_BYTE_ARRAY_LITERAL(payload), - key_pair, - output, - &cose_sign1); + key_pair, + out_buffer, + &cose_sign1); if(err) { return 20; } @@ -99,8 +102,43 @@ int32_t mini_sign1_sign_test(void) { return 30; } + if(q_useful_buf_compare(verified_payload, Q_USEFUL_BUF_FROM_BYTE_ARRAY_LITERAL(payload))) { + return 50; + } + + /* Test with a buffer that is too small */ + out_buffer.len -= 30; + err = t_cose_mini_sign1_sign(Q_USEFUL_BUF_FROM_BYTE_ARRAY_LITERAL(payload), + key_pair, + out_buffer, + &cose_sign1); + //if(err != T_COSE_ERR_TOO_SMALL) { + // return 100; + //} + + /* Payload bigger than UINT16_MAX */ + struct q_useful_buf_c long_payload = Q_USEFUL_BUF_FROM_BYTE_ARRAY_LITERAL(payload); + long_payload.len = UINT16_MAX + 1; + + err = t_cose_mini_sign1_sign(long_payload, + key_pair, + out_buffer, + &cose_sign1); + if(err != T_COSE_ERR_TOO_LONG) { + return 200; + } + + /* Wrong key type */ + // TODO: psa signing doesn't check crypto lib. Is that OK? + key_pair.crypto_lib = (enum t_cose_crypto_lib_t) 42; + err = t_cose_mini_sign1_sign(Q_USEFUL_BUF_FROM_BYTE_ARRAY_LITERAL(payload), + key_pair, + out_buffer, + &cose_sign1); + if(err != T_COSE_ERR_INCORRECT_KEY_FOR_LIB) { + return 200; + } + return 0; } - -// TODO: test for output buffer too small From 9a573f423fedd51943f90fb07b066f1f639d9245 Mon Sep 17 00:00:00 2001 From: Laurence Lundblade Date: Sun, 25 Jun 2023 03:09:08 -0700 Subject: [PATCH 09/11] Add mini sign to Cmake --- CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4f0c8682..3efc8e27 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,6 +67,7 @@ set(T_COSE_SRC_COMMON src/t_cose_sign1_verify.c src/t_cose_util.c src/t_cose_short_circuit.c + src/t_cose_mini_sign1_sign.c ) find_package(QCBOR REQUIRED) @@ -106,6 +107,7 @@ if (BUILD_TESTS) test/run_tests.c test/t_cose_make_test_messages.c test/t_cose_test.c + test/t_cose_mini_sign1_sign_test.c ) if (NOT CRYPTO_PROVIDER STREQUAL "Test") From 6d6a45c73cb17c7e94cb6e253c62ba21c8a0df4a Mon Sep 17 00:00:00 2001 From: Laurence Lundblade Date: Tue, 8 Aug 2023 00:49:41 -0700 Subject: [PATCH 10/11] Documentation and test improvements --- Makefile.psa | 4 +- inc/t_cose/t_cose_mini_sign1_sign.h | 55 ++++++----- src/t_cose_mini_sign1_sign.c | 70 ++++++++------ test/t_cose_mini_sign1_sign_test.c | 142 ++++++++++++++++++++-------- 4 files changed, 179 insertions(+), 92 deletions(-) diff --git a/Makefile.psa b/Makefile.psa index 3f9c28f1..038cea58 100644 --- a/Makefile.psa +++ b/Makefile.psa @@ -56,7 +56,7 @@ C_OPTS=-Os -fPIC # ---- T_COSE Config and test options ---- TEST_CONFIG_OPTS= -TEST_OBJ=test/t_cose_test.o test/run_tests.o test/t_cose_sign_verify_test.o test/t_cose_make_test_messages.o $(CRYPTO_TEST_OBJ) +TEST_OBJ=test/t_cose_test.o test/run_tests.o test/t_cose_sign_verify_test.o test/t_cose_make_test_messages.o test/t_cose_mini_sign1_sign_test.o $(CRYPTO_TEST_OBJ) # ---- the main body that is invariant ---- @@ -64,7 +64,7 @@ INC=-I inc -I test -I src ALL_INC=$(INC) $(CRYPTO_INC) $(QCBOR_INC) CFLAGS=$(CMD_LINE) $(ALL_INC) $(C_OPTS) $(TEST_CONFIG_OPTS) $(CRYPTO_CONFIG_OPTS) -SRC_OBJ=src/t_cose_sign1_verify.o src/t_cose_sign1_sign.o src/t_cose_util.o src/t_cose_parameters.o src/t_cose_short_circuit.o +SRC_OBJ=src/t_cose_sign1_verify.o src/t_cose_sign1_sign.o src/t_cose_mini_sign1_sign.o src/t_cose_util.o src/t_cose_parameters.o src/t_cose_short_circuit.o .PHONY: all install install_headers install_so uninstall clean diff --git a/inc/t_cose/t_cose_mini_sign1_sign.h b/inc/t_cose/t_cose_mini_sign1_sign.h index 1c33517f..435f329f 100644 --- a/inc/t_cose/t_cose_mini_sign1_sign.h +++ b/inc/t_cose/t_cose_mini_sign1_sign.h @@ -1,5 +1,5 @@ /* - * t_cose_mini_sign1_sign.h + * t_cose_mini_sign1_sign.h * * Copyright 2022-2023, Laurence Lundblade * @@ -29,7 +29,7 @@ extern "C" { /* The output buffer must be this much larger than the payload size. */ #define T_COSE_MINI_SIGN_SIZE_OVERHEAD_ES256 \ 1 + /* Open the array */ \ - 6 + /* The header parameters */ \ + 5 + /* The header parameters */ \ 3 + /* The CBOR head of the payload */ \ /* The payload -- add this in yourself */ \ 2 + /* CBOR head of signature */ \ @@ -49,7 +49,7 @@ extern "C" { 3 + /* The CBOR head of the payload */ \ /* The payload -- add this in yourself */ \ 2 + /* CBOR head of signature */ \ - 128 /* T_COSE_EC_P512_SIG_SIZE */ + 132 /* T_COSE_EC_P512_SIG_SIZE */ /** @@ -65,34 +65,37 @@ extern "C" { * payload. * Other errors related to invocation of the crypto algorithms. * - * This is a small object code version of t_cose_sign1_sign(). The - * small object code is achieved by fixing the algorithm at compile - * time (the default is COSE ES256) and by not allowing or outputting - * any header parameter except the algorithm ID. There is also - * a maximum size of the payload at UINT16_MAX. + * This signs a payload to make a COSE_Sign1 in the simplest possible + * way. The object code for this is very small. This is achieved by + * fixing the algorithm at compile time, not allowing any header + * parameters but the signing algorithm and limiting the payload size + * to \c UINT16_MAX. The default algorithm is COSE ES256 (EC with the + * secp256r1 curve). + * + * See t_cose_sign1_sign() for full-featured signing. * - * Even if you don't need small object code, this is - * a super easy to use COSE Sign1 API if ES256 is good enough - * and you don't need any other header parameters. + * The inputs are a payload to sign and a signing key. The signing key + * is a handle or pointer to a key usable with the crypto library this + * is linked against (probably OpenSSL or Mbed TLS). The key + * set up is the same as in the t_cose examples. * - * See \ref T_COSE_MINI_SIGN_SIZE_OVERHEAD_ES256 for a compile time - * constant that gives the size over and above the payload size - * for the output buffer. If \ref output_buffer is too small - * an error will be returned. + * An output buffer must be given sized large enough to hold the + * COSE_Sign1 message produced. The size of this is \ref + * T_COSE_MINI_SIGN_SIZE_OVERHEAD_ES256 larger than the payload. If + * \c output_buffer is too small, an error will be returned. * - * The object code size is about 500 bytes plus the crypto library. - * This works with either OpenSSL and PSA Crypto (MbedTLS). It - * is less total object code with PSA Crypto. This contrasts - * with about 1500 bytes plus QCBOR plus the crypto library - * for t_cose_sign1_sign(). + * This does NOT need to link with a CBOR encoder. It does need to + * link with a cryptographic library. OpenSSL and Mbed TLS are + * supported. It uses the t_cose_crypto.h layer to interface with the + * cryptographic library. It should be easy adapt this to other + * cryptographic libraries. * - * ES384 and ES512 are also supported, but you have to modify - * the source to switch to one of them. The source could be - * further modified to support RSA. + * ES384 and ES512 are also supported, but you have to modify the + * source to switch to one of them. The source could be further + * modified to support RSA. * - * See comments in the source code for changing the algorithm that - * is supported, adding support for headers or reducing the object - * code even futher. + * See comments in the source code to change the algorithm and + * discussion about other modifications. */ enum t_cose_err_t t_cose_mini_sign1_sign(struct q_useful_buf_c payload, diff --git a/src/t_cose_mini_sign1_sign.c b/src/t_cose_mini_sign1_sign.c index 624f6f27..454619c6 100644 --- a/src/t_cose_mini_sign1_sign.c +++ b/src/t_cose_mini_sign1_sign.c @@ -1,7 +1,7 @@ /* * t_cose_mini_sign1_sign.c * - * Copyright 2022, Laurence Lundblade + * Copyright 2022-2023, Laurence Lundblade * * SPDX-License-Identifier: BSD-3-Clause * @@ -12,15 +12,28 @@ #include "t_cose/t_cose_common.h" #include "t_cose_crypto.h" -#include "qcbor/UsefulBuf.h" /* + * This depends on several t_cose header files for definitions + * of COSE constants, error codes and such. It indirectly + * depends on one QCBOR header file for useful_buf. + * + * This depends on a crypto library for the hash and + * public key cryptography. Access to the crypto library + * goes through t_cose_crypto and thus requires the + * C source file for the crypto adaptor for the particular + * crypto library. + * * This could be modified to support other header parameters like the - * kid and the object code would still be bigger, but still very + * kid and the object code would be bigger, but still very * small. * - * Or on the other hand, this could be modified to support only a - * fixed-size payload to make the object code even smaller. + * There's lots that could be done to make this smaller + * if more is known about the use context. For example, + * if the payload is fixed size the CBOR head encoder + * can be removed. The crypto interface is also + * a candidate for optimization. Maybe you call your + * crypto library direct. */ @@ -60,7 +73,7 @@ #define MINI_SIGN_HASH COSE_ALGORITHM_SHA_512 #define MINI_SIGN_HASH_LEN T_COSE_CRYPTO_SHA512_SIZE -#define MINI_SIGN_ALG T_COSE_ALGORITHM_ES521 +#define MINI_SIGN_ALG T_COSE_ALGORITHM_ES512 #define MINI_SIGN_ALG_ID_BYTES 0x38, 0x23 /* The literal byte that appears in the CBOR encoding */ #define MINI_SIGN_SIG_LEN T_COSE_EC_P512_SIG_SIZE @@ -82,7 +95,7 @@ /* * This is hard-coded bytes for the start of the CBOR for the following * CBOR that are the to-be-signed bytes. Hard coding like this saves - * writing code to create it. + * writing code to create it and linking in a CBOR encoder. * * Sig_structure = [ * context : "Signature" / "Signature1" / "CounterSignature", @@ -94,8 +107,8 @@ */ static const uint8_t start_sig_struct[] = { 0x84, - 0x6A,'S', 'i', 'g', 'n', 'a', 't', 'u', 'r', 'e', '1', - PROT_HEADERS, // bstr wrapped protected header wtih algorithm ID + 0x6A, 'S', 'i', 'g', 'n', 'a', 't', 'u', 'r', 'e', '1', + PROT_HEADERS, /* bstr wrapped protected header wtih algorithm ID */ 0x40, /* Empty bstr for aad */ }; @@ -104,12 +117,13 @@ static const uint8_t start_sig_struct[] = { */ static const uint8_t start_cose_sign1[] = { 0x84, - PROT_HEADERS, // bstr wrapped protected header wtih algorithm ID + PROT_HEADERS, /* bstr wrapped protected header wtih algorithm ID */ 0xa0, /* no unprotected headers, put some here if you want */ }; -/* The Hard coded bytes for the CBOR head for the signature. It is less - * code to hard code than to encode using encode_bstr_head() */ +/* The hard coded bytes for the CBOR head for the signature. It is less + * code to hard code than to encode using encode_bstr_head(). Sig + * is always between 24 and 255 bytes so 0x58. */ static const uint8_t cose_sign1_sig_start[] = { 0x58, MINI_SIGN_SIG_LEN }; @@ -187,8 +201,8 @@ t_cose_mini_sign1_sign(const struct q_useful_buf_c payload, payload_head = encode_bstr_head(payload.len, payload_head_buffer); if(payload_head.ptr == NULL) { - /* The payload is too large (the only reason encode_bstr_head() - * errors out). + /* The payload is too large, the only reason + * encode_bstr_head() errors out. */ return T_COSE_ERR_TOO_LONG; } @@ -197,6 +211,8 @@ t_cose_mini_sign1_sign(const struct q_useful_buf_c payload, /* --- hash the Sig_structure --- */ /* Don't actually have to create the Sig_structure fully in * memory. Just have to compute the hash of it. */ + /* If you are really confident in your crypto library hash , you + * could remove these error checks and save more object code. */ err = t_cose_crypto_hash_start(&hash_ctx, MINI_SIGN_HASH); if(err != T_COSE_SUCCESS) { goto Done; @@ -212,9 +228,9 @@ t_cose_mini_sign1_sign(const struct q_useful_buf_c payload, } /* ---- Size check ---- */ - /* Calculate the length of the output buffer required. It is - * just the payload plus a constant. This one check covers - * all the memcpy() calls below. + /* Calculate the length of the output buffer required. It is just + * the payload plus a constant. This one check covers all the + * memcpy() calls and signing operation below. */ const size_t required_len = sizeof(start_cose_sign1) + MAX_CBOR_HEAD + @@ -242,15 +258,15 @@ t_cose_mini_sign1_sign(const struct q_useful_buf_c payload, copy_ptr += sizeof(cose_sign1_sig_start); const size_t u_len = (size_t)(copy_ptr - (uint8_t *)output_buffer.ptr); - - - /* This won't go negative because of the check against required_len above - * so the cast is safe. + /* This subtraction won't go negative because of the check against + required_len above */ + + /* Set up for t_cose_crypto_sign to write signature directly + * into output buffer. */ signature_buffer.len = output_buffer.len - u_len; signature_buffer.ptr = copy_ptr; - err = t_cose_crypto_sign(MINI_SIGN_ALG, signing_key, computed_hash, @@ -266,11 +282,11 @@ t_cose_mini_sign1_sign(const struct q_useful_buf_c payload, * UsefulBuf that took a few hours of debugging to find. Or maybe * I'm not as sharp as I used to be... * - * Or said another way, this code doesn't have the same security / - * buffer level that QCBOR has. It hasn't gone through the same - * security review and static analysis and such yet either. In - * theory it is safe, but I'd advise you review and analyze - * before security-critical use. + * Or said another way, this code doesn't have the same buffer + * security level that QCBOR has. It hasn't gone through the same + * security review and static analysis and such yet either. I am + * pretty confident it is safe, but I'd advise you review and + * analyze before security-critical use. */ Done: diff --git a/test/t_cose_mini_sign1_sign_test.c b/test/t_cose_mini_sign1_sign_test.c index 5f2f2894..2ce58532 100644 --- a/test/t_cose_mini_sign1_sign_test.c +++ b/test/t_cose_mini_sign1_sign_test.c @@ -1,7 +1,7 @@ /* - * t_cose_mini_sign1_sign_test.c + * t_cose_mini_sign1_sign_test.c * - * Copyright 2022, Laurence Lundblade + * Copyright 2022-2023, Laurence Lundblade * * SPDX-License-Identifier: BSD-3-Clause * @@ -14,7 +14,7 @@ #include "t_cose/t_cose_mini_sign1_sign.h" #include "t_cose/t_cose_sign1_verify.h" -static const uint8_t payload[] = { +static const uint8_t sample_payload[] = { 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, @@ -66,25 +66,17 @@ static const uint8_t payload[] = { }; -int32_t mini_sign1_sign_test(void) { - - enum t_cose_err_t err; - MakeUsefulBufOnStack( out_buffer, sizeof(payload) + T_COSE_MINI_SIGN_SIZE_OVERHEAD_ES512); - struct q_useful_buf_c cose_sign1; - struct t_cose_key key_pair; +int32_t +mini_sign1_verify_one_payload(struct q_useful_buf_c payload, + struct t_cose_key key_pair, + struct q_useful_buf out_buffer) +{ struct t_cose_sign1_verify_ctx verify_ctx; struct q_useful_buf_c verified_payload; + enum t_cose_err_t err; + struct q_useful_buf_c cose_sign1; - // TODO: tests for different algorithms - // How to do this with compiled-in algorithm? - - err = make_key_pair(T_COSE_ALGORITHM_ES256, &key_pair); - if(err) { - return 10; - } - - /* The main happy-path test */ - err = t_cose_mini_sign1_sign(Q_USEFUL_BUF_FROM_BYTE_ARRAY_LITERAL(payload), + err = t_cose_mini_sign1_sign(payload, key_pair, out_buffer, &cose_sign1); @@ -92,7 +84,6 @@ int32_t mini_sign1_sign_test(void) { return 20; } - t_cose_sign1_verify_init(&verify_ctx, 0); t_cose_sign1_set_verification_key(&verify_ctx, key_pair); @@ -102,22 +93,109 @@ int32_t mini_sign1_sign_test(void) { return 30; } - if(q_useful_buf_compare(verified_payload, Q_USEFUL_BUF_FROM_BYTE_ARRAY_LITERAL(payload))) { + if(q_useful_buf_compare(verified_payload, payload)) { return 50; } + return 0; +} + + + +/* Compile the library and this test case with each of these to + * test the compile-time selection of the algorithm. Run the test + * each time. */ +#if !defined(T_COSE_MINI_SIGN_SELECT_ES256) && \ + !defined(T_COSE_MINI_SIGN_SELECT_ES384) && \ + !defined(T_COSE_MINI_SIGN_SELECT_ES512) +#define T_COSE_MINI_SIGN_SELECT_ES256 +#endif + + +#if defined(T_COSE_MINI_SIGN_SELECT_ES256) + + #define MINI_SIGN_ALG T_COSE_ALGORITHM_ES256 + #define SIZE_OVERHEAD T_COSE_MINI_SIGN_SIZE_OVERHEAD_ES256 + +#elif defined(T_COSE_MINI_SIGN_SELECT_ES384) + + #define MINI_SIGN_ALG T_COSE_ALGORITHM_ES384 + #define SIZE_OVERHEAD T_COSE_MINI_SIGN_SIZE_OVERHEAD_ES384 + +#elif defined(T_COSE_MINI_SIGN_SELECT_ES512) + + #define MINI_SIGN_ALG T_COSE_ALGORITHM_ES512 + #define SIZE_OVERHEAD T_COSE_MINI_SIGN_SIZE_OVERHEAD_ES512 + +#endif + + +int32_t mini_sign1_sign_test(void) { + + enum t_cose_err_t err; + MakeUsefulBufOnStack( out_buffer, sizeof(sample_payload) + SIZE_OVERHEAD); + struct q_useful_buf_c cose_sign1; + struct t_cose_key key_pair; + struct t_cose_key null_key_pair; + int32_t test_result; + struct q_useful_buf_c payload; + + + // TODO: tests for different algorithms + // How to do this with compiled-in algorithm? + + err = make_key_pair(MINI_SIGN_ALG, &key_pair); + if(err) { + return 10; + } + + /* The main happy-path test for serveral payload sizes */ + payload = Q_USEFUL_BUF_FROM_BYTE_ARRAY_LITERAL(sample_payload); + test_result = mini_sign1_verify_one_payload(payload, + key_pair, + out_buffer); + if(test_result) { + return test_result; + } + + payload.len = 254; + test_result = mini_sign1_verify_one_payload(payload, + key_pair, + out_buffer); + if(test_result) { + return test_result; + } + + payload.len = 2; + test_result = mini_sign1_verify_one_payload(payload, + key_pair, + out_buffer); + if(test_result) { + return test_result; + } + + /* With a bad key pair */ + memset(&null_key_pair, 0, sizeof(struct t_cose_key)); + err = t_cose_mini_sign1_sign(Q_USEFUL_BUF_FROM_BYTE_ARRAY_LITERAL(sample_payload), + null_key_pair, + out_buffer, + &cose_sign1); + if(err != T_COSE_ERR_SIG_FAIL && err != T_COSE_ERR_INCORRECT_KEY_FOR_LIB) { + return 120; + } + /* Test with a buffer that is too small */ out_buffer.len -= 30; - err = t_cose_mini_sign1_sign(Q_USEFUL_BUF_FROM_BYTE_ARRAY_LITERAL(payload), + err = t_cose_mini_sign1_sign(Q_USEFUL_BUF_FROM_BYTE_ARRAY_LITERAL(sample_payload), key_pair, out_buffer, &cose_sign1); - //if(err != T_COSE_ERR_TOO_SMALL) { - // return 100; - //} + if(err != T_COSE_ERR_TOO_SMALL) { + return 100; + } /* Payload bigger than UINT16_MAX */ - struct q_useful_buf_c long_payload = Q_USEFUL_BUF_FROM_BYTE_ARRAY_LITERAL(payload); + struct q_useful_buf_c long_payload = Q_USEFUL_BUF_FROM_BYTE_ARRAY_LITERAL(sample_payload); long_payload.len = UINT16_MAX + 1; err = t_cose_mini_sign1_sign(long_payload, @@ -128,17 +206,7 @@ int32_t mini_sign1_sign_test(void) { return 200; } - /* Wrong key type */ - // TODO: psa signing doesn't check crypto lib. Is that OK? - key_pair.crypto_lib = (enum t_cose_crypto_lib_t) 42; - err = t_cose_mini_sign1_sign(Q_USEFUL_BUF_FROM_BYTE_ARRAY_LITERAL(payload), - key_pair, - out_buffer, - &cose_sign1); - if(err != T_COSE_ERR_INCORRECT_KEY_FOR_LIB) { - return 200; - } + free_key_pair(key_pair); return 0; } - From 0b5e47c9354390f6da07464f9f1706c3c3be1657 Mon Sep 17 00:00:00 2001 From: Laurence Lundblade Date: Wed, 9 Aug 2023 14:33:48 -0700 Subject: [PATCH 11/11] Don't test mini sign with test crypto --- CMakeLists.txt | 2 +- Makefile.test | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3efc8e27..0913b0aa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -107,11 +107,11 @@ if (BUILD_TESTS) test/run_tests.c test/t_cose_make_test_messages.c test/t_cose_test.c - test/t_cose_mini_sign1_sign_test.c ) if (NOT CRYPTO_PROVIDER STREQUAL "Test") list(APPEND TEST_SRC_COMMON test/t_cose_sign_verify_test.c) + list(APPEND TEST_SRC_COMMON test/t_cose_mini_sign1_sign_test.c) endif() if (CRYPTO_PROVIDER STREQUAL "MbedTLS") diff --git a/Makefile.test b/Makefile.test index 7a233758..572154a7 100644 --- a/Makefile.test +++ b/Makefile.test @@ -46,7 +46,7 @@ INC=-I inc -I test -I src ALL_INC=$(INC) $(CRYPTO_INC) $(QCBOR_INC) CFLAGS=$(CMD_LINE) $(ALL_INC) $(C_OPTS) $(TEST_CONFIG_OPTS) $(CRYPTO_CONFIG_OPTS) -SRC_OBJ=src/t_cose_sign1_verify.o src/t_cose_sign1_sign.o src/t_cose_util.o src/t_cose_parameters.o src/t_cose_short_circuit.o +SRC_OBJ=src/t_cose_sign1_verify.o src/t_cose_sign1_sign.o src/t_cose_mini_sign1_sign.o src/t_cose_util.o src/t_cose_parameters.o src/t_cose_short_circuit.o .PHONY: all clean