diff --git a/CMakeLists.txt b/CMakeLists.txt index 5051626d2..08ca29eec 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,10 +2,10 @@ cmake_minimum_required(VERSION 2.6.4) project (cryptoauthlib C) # Set the current release version -set(VERSION "3.3.0") +set(VERSION "3.3.1") set(VERSION_MAJOR 3) set(VERSION_MINOR 3) -set(VERSION_PATCH 0) +set(VERSION_PATCH 1) # Build Options option(BUILD_TESTS "Create Test Application with library" OFF) diff --git a/app/pkcs11/example_cert_chain.c b/app/pkcs11/example_cert_chain.c index 798770757..2cb4f64bf 100644 --- a/app/pkcs11/example_cert_chain.c +++ b/app/pkcs11/example_cert_chain.c @@ -56,35 +56,35 @@ const atcacert_cert_element_t g_cert_elements_1_signer[] = { }; const uint8_t g_cert_template_1_signer[] = { - 0x30, 0x82, 0x01, 0xc8, 0x30, 0x82, 0x01, 0x6e, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x57, - 0x06, 0x2e, 0xf0, 0x05, 0xea, 0x8a, 0x70, 0x44, 0xff, 0x1b, 0x90, 0x00, 0x21, 0x78, 0xd6, 0x30, - 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x30, 0x31, 0x14, 0x30, - 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, - 0x49, 0x6e, 0x63, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f, 0x45, 0x78, - 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, - 0x0d, 0x31, 0x37, 0x30, 0x36, 0x30, 0x37, 0x31, 0x37, 0x35, 0x36, 0x31, 0x32, 0x5a, 0x17, 0x0d, - 0x32, 0x37, 0x30, 0x36, 0x30, 0x37, 0x31, 0x37, 0x35, 0x36, 0x31, 0x32, 0x5a, 0x30, 0x34, 0x31, - 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, - 0x65, 0x20, 0x49, 0x6e, 0x63, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x13, - 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x20, 0x46, - 0x46, 0x46, 0x46, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, - 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xb1, 0xf5, - 0x9c, 0xbe, 0x22, 0x11, 0x7f, 0x28, 0x2f, 0x7f, 0x2e, 0xcb, 0xa2, 0x8c, 0x30, 0x3b, 0xae, 0x59, - 0x45, 0xb9, 0x5c, 0x0e, 0xba, 0xaa, 0x9b, 0x81, 0x73, 0x52, 0x63, 0x41, 0xbf, 0x37, 0x3c, 0x2e, - 0xdd, 0xcd, 0xea, 0x0e, 0x7c, 0x9d, 0x90, 0xea, 0x25, 0x9c, 0x64, 0xeb, 0xc6, 0x54, 0x47, 0x32, - 0x81, 0x63, 0xbf, 0x42, 0x5f, 0xdd, 0x5a, 0x3f, 0xd5, 0x71, 0x81, 0x9b, 0x77, 0x44, 0xa3, 0x66, - 0x30, 0x64, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, - 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, - 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, - 0x14, 0x81, 0x1d, 0xc6, 0x7c, 0x0f, 0x18, 0x2b, 0x65, 0x96, 0xeb, 0x22, 0x73, 0xdb, 0xf3, 0x23, - 0x63, 0x6d, 0x79, 0x0f, 0xc8, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, - 0x80, 0x14, 0xdb, 0x2a, 0x0d, 0x06, 0x05, 0xc7, 0x98, 0xbc, 0xda, 0xc0, 0x34, 0x67, 0x66, 0xf4, - 0xe2, 0xb0, 0x61, 0xa3, 0xd2, 0xc8, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, - 0x03, 0x02, 0x03, 0x48, 0x00, 0x30, 0x45, 0x02, 0x20, 0x49, 0xfe, 0xdf, 0xc9, 0x94, 0xe3, 0x07, - 0xdb, 0x08, 0xb3, 0x99, 0x9e, 0x04, 0xe4, 0x78, 0xe5, 0xf8, 0xb9, 0x09, 0xa9, 0xf0, 0x41, 0x66, - 0xc6, 0x69, 0x1b, 0x87, 0x30, 0x86, 0x10, 0xaf, 0x64, 0x02, 0x21, 0x00, 0xc8, 0xd6, 0x86, 0x61, - 0x94, 0x95, 0xdb, 0x45, 0xb3, 0x40, 0x8e, 0xac, 0x14, 0x9a, 0x19, 0xb6, 0x8c, 0x5c, 0x79, 0x9d, - 0x06, 0xcb, 0x52, 0x08, 0xa0, 0x1f, 0x49, 0x8b, 0x22, 0x4e, 0x52, 0x71 + 0x30, 0x82, 0x01, 0xc8, 0x30, 0x82, 0x01, 0x6e, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x57, + 0x06, 0x2e, 0xf0, 0x05, 0xea, 0x8a, 0x70, 0x44, 0xff, 0x1b, 0x90, 0x00, 0x21, 0x78, 0xd6, 0x30, + 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x30, 0x31, 0x14, 0x30, + 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, + 0x49, 0x6e, 0x63, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f, 0x45, 0x78, + 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, + 0x0d, 0x31, 0x37, 0x30, 0x36, 0x30, 0x37, 0x31, 0x37, 0x35, 0x36, 0x31, 0x32, 0x5a, 0x17, 0x0d, + 0x32, 0x37, 0x30, 0x36, 0x30, 0x37, 0x31, 0x37, 0x35, 0x36, 0x31, 0x32, 0x5a, 0x30, 0x34, 0x31, + 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, + 0x65, 0x20, 0x49, 0x6e, 0x63, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x13, + 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x20, 0x46, + 0x46, 0x46, 0x46, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, + 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xb1, 0xf5, + 0x9c, 0xbe, 0x22, 0x11, 0x7f, 0x28, 0x2f, 0x7f, 0x2e, 0xcb, 0xa2, 0x8c, 0x30, 0x3b, 0xae, 0x59, + 0x45, 0xb9, 0x5c, 0x0e, 0xba, 0xaa, 0x9b, 0x81, 0x73, 0x52, 0x63, 0x41, 0xbf, 0x37, 0x3c, 0x2e, + 0xdd, 0xcd, 0xea, 0x0e, 0x7c, 0x9d, 0x90, 0xea, 0x25, 0x9c, 0x64, 0xeb, 0xc6, 0x54, 0x47, 0x32, + 0x81, 0x63, 0xbf, 0x42, 0x5f, 0xdd, 0x5a, 0x3f, 0xd5, 0x71, 0x81, 0x9b, 0x77, 0x44, 0xa3, 0x66, + 0x30, 0x64, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, + 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, + 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, + 0x14, 0x81, 0x1d, 0xc6, 0x7c, 0x0f, 0x18, 0x2b, 0x65, 0x96, 0xeb, 0x22, 0x73, 0xdb, 0xf3, 0x23, + 0x63, 0x6d, 0x79, 0x0f, 0xc8, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, + 0x80, 0x14, 0xdb, 0x2a, 0x0d, 0x06, 0x05, 0xc7, 0x98, 0xbc, 0xda, 0xc0, 0x34, 0x67, 0x66, 0xf4, + 0xe2, 0xb0, 0x61, 0xa3, 0xd2, 0xc8, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, + 0x03, 0x02, 0x03, 0x48, 0x00, 0x30, 0x45, 0x02, 0x20, 0x49, 0xfe, 0xdf, 0xc9, 0x94, 0xe3, 0x07, + 0xdb, 0x08, 0xb3, 0x99, 0x9e, 0x04, 0xe4, 0x78, 0xe5, 0xf8, 0xb9, 0x09, 0xa9, 0xf0, 0x41, 0x66, + 0xc6, 0x69, 0x1b, 0x87, 0x30, 0x86, 0x10, 0xaf, 0x64, 0x02, 0x21, 0x00, 0xc8, 0xd6, 0x86, 0x61, + 0x94, 0x95, 0xdb, 0x45, 0xb3, 0x40, 0x8e, 0xac, 0x14, 0x9a, 0x19, 0xb6, 0x8c, 0x5c, 0x79, 0x9d, + 0x06, 0xcb, 0x52, 0x08, 0xa0, 0x1f, 0x49, 0x8b, 0x22, 0x4e, 0x52, 0x71 }; const atcacert_def_t g_cert_def_1_signer = { @@ -163,33 +163,33 @@ const atcacert_def_t g_cert_def_1_signer = { }; const uint8_t g_cert_template_2_device[] = { - 0x30, 0x82, 0x01, 0xa6, 0x30, 0x82, 0x01, 0x4b, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x41, - 0xa6, 0x8b, 0xe4, 0x36, 0xdd, 0xc3, 0xd8, 0x39, 0xfa, 0xbd, 0xd7, 0x27, 0xd9, 0x74, 0xe7, 0x30, - 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x34, 0x31, 0x14, 0x30, - 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, - 0x49, 0x6e, 0x63, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x13, 0x45, 0x78, - 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x20, 0x46, 0x46, 0x46, - 0x46, 0x30, 0x20, 0x17, 0x0d, 0x31, 0x37, 0x30, 0x37, 0x31, 0x30, 0x32, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x5a, 0x18, 0x0f, 0x33, 0x30, 0x30, 0x30, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, - 0x35, 0x39, 0x5a, 0x30, 0x2f, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, - 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x31, 0x17, 0x30, 0x15, 0x06, - 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0e, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x44, 0x65, - 0x76, 0x69, 0x63, 0x65, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, - 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x96, - 0x27, 0xf1, 0x3e, 0x80, 0xac, 0xf9, 0xd4, 0x12, 0xce, 0x3b, 0x0d, 0x68, 0xf7, 0x4e, 0xb2, 0xc6, - 0x07, 0x35, 0x00, 0xb7, 0x78, 0x5b, 0xac, 0xe6, 0x50, 0x30, 0x54, 0x77, 0x7f, 0xc8, 0x62, 0x21, - 0xce, 0xf2, 0x5a, 0x9a, 0x9e, 0x86, 0x40, 0xc2, 0x29, 0xd6, 0x4a, 0x32, 0x1e, 0xb9, 0x4a, 0x1b, - 0x1c, 0x94, 0xf5, 0x39, 0x88, 0xae, 0xfe, 0x49, 0xcc, 0xfd, 0xbf, 0x8a, 0x0d, 0x34, 0xb8, 0xa3, - 0x42, 0x30, 0x40, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x2d, 0xda, - 0x6c, 0x36, 0xd5, 0xa5, 0x5a, 0xce, 0x97, 0x10, 0x3d, 0xbb, 0xaf, 0x9c, 0x66, 0x2a, 0xcd, 0x3e, - 0xe6, 0xcf, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xc6, - 0x70, 0xe0, 0x5e, 0x8a, 0x45, 0x0d, 0xb8, 0x2c, 0x00, 0x2a, 0x40, 0x06, 0x39, 0x4c, 0x19, 0x58, - 0x04, 0x35, 0x76, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, - 0x49, 0x00, 0x30, 0x46, 0x02, 0x21, 0x00, 0xe1, 0xfc, 0x00, 0x23, 0xc1, 0x3d, 0x01, 0x3f, 0x22, - 0x31, 0x0b, 0xf0, 0xb8, 0xf4, 0xf4, 0x22, 0xfc, 0x95, 0x96, 0x33, 0x9c, 0xb9, 0x62, 0xb1, 0xfc, - 0x8a, 0x2d, 0xa8, 0x5c, 0xee, 0x67, 0x72, 0x02, 0x21, 0x00, 0xa1, 0x0d, 0x47, 0xe4, 0xfd, 0x0d, - 0x15, 0xd8, 0xde, 0xa1, 0xb5, 0x96, 0x28, 0x4e, 0x7a, 0x0b, 0xbe, 0xcc, 0xec, 0xe8, 0x8e, 0xcc, - 0x7a, 0x31, 0xb3, 0x00, 0x8b, 0xc0, 0x2e, 0x4f, 0x99, 0xc5 + 0x30, 0x82, 0x01, 0xa6, 0x30, 0x82, 0x01, 0x4b, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x41, + 0xa6, 0x8b, 0xe4, 0x36, 0xdd, 0xc3, 0xd8, 0x39, 0xfa, 0xbd, 0xd7, 0x27, 0xd9, 0x74, 0xe7, 0x30, + 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x34, 0x31, 0x14, 0x30, + 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, + 0x49, 0x6e, 0x63, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x13, 0x45, 0x78, + 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x20, 0x46, 0x46, 0x46, + 0x46, 0x30, 0x20, 0x17, 0x0d, 0x31, 0x37, 0x30, 0x37, 0x31, 0x30, 0x32, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x5a, 0x18, 0x0f, 0x33, 0x30, 0x30, 0x30, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, + 0x35, 0x39, 0x5a, 0x30, 0x2f, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, + 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x31, 0x17, 0x30, 0x15, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0e, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x44, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, + 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x96, + 0x27, 0xf1, 0x3e, 0x80, 0xac, 0xf9, 0xd4, 0x12, 0xce, 0x3b, 0x0d, 0x68, 0xf7, 0x4e, 0xb2, 0xc6, + 0x07, 0x35, 0x00, 0xb7, 0x78, 0x5b, 0xac, 0xe6, 0x50, 0x30, 0x54, 0x77, 0x7f, 0xc8, 0x62, 0x21, + 0xce, 0xf2, 0x5a, 0x9a, 0x9e, 0x86, 0x40, 0xc2, 0x29, 0xd6, 0x4a, 0x32, 0x1e, 0xb9, 0x4a, 0x1b, + 0x1c, 0x94, 0xf5, 0x39, 0x88, 0xae, 0xfe, 0x49, 0xcc, 0xfd, 0xbf, 0x8a, 0x0d, 0x34, 0xb8, 0xa3, + 0x42, 0x30, 0x40, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x2d, 0xda, + 0x6c, 0x36, 0xd5, 0xa5, 0x5a, 0xce, 0x97, 0x10, 0x3d, 0xbb, 0xaf, 0x9c, 0x66, 0x2a, 0xcd, 0x3e, + 0xe6, 0xcf, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xc6, + 0x70, 0xe0, 0x5e, 0x8a, 0x45, 0x0d, 0xb8, 0x2c, 0x00, 0x2a, 0x40, 0x06, 0x39, 0x4c, 0x19, 0x58, + 0x04, 0x35, 0x76, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, + 0x49, 0x00, 0x30, 0x46, 0x02, 0x21, 0x00, 0xe1, 0xfc, 0x00, 0x23, 0xc1, 0x3d, 0x01, 0x3f, 0x22, + 0x31, 0x0b, 0xf0, 0xb8, 0xf4, 0xf4, 0x22, 0xfc, 0x95, 0x96, 0x33, 0x9c, 0xb9, 0x62, 0xb1, 0xfc, + 0x8a, 0x2d, 0xa8, 0x5c, 0xee, 0x67, 0x72, 0x02, 0x21, 0x00, 0xa1, 0x0d, 0x47, 0xe4, 0xfd, 0x0d, + 0x15, 0xd8, 0xde, 0xa1, 0xb5, 0x96, 0x28, 0x4e, 0x7a, 0x0b, 0xbe, 0xcc, 0xec, 0xe8, 0x8e, 0xcc, + 0x7a, 0x31, 0xb3, 0x00, 0x8b, 0xc0, 0x2e, 0x4f, 0x99, 0xc5 }; const atcacert_def_t g_cert_def_2_device = { diff --git a/app/pkcs11/example_pkcs11_config.c b/app/pkcs11/example_pkcs11_config.c index 24758e24e..7fdfdfb7f 100644 --- a/app/pkcs11/example_pkcs11_config.c +++ b/app/pkcs11/example_pkcs11_config.c @@ -14,11 +14,11 @@ #endif #ifndef pkcs11configLABEL_DEVICE_PRIVATE_KEY_FOR_TLS -#define pkcs11configLABEL_DEVICE_PRIVATE_KEY_FOR_TLS pkcs11configLABEL_DEVICE_CERTIFICATE_FOR_TLS +#define pkcs11configLABEL_DEVICE_PRIVATE_KEY_FOR_TLS "device private" #endif #ifndef pkcs11configLABEL_DEVICE_PUBLIC_KEY_FOR_TLS -#define pkcs11configLABEL_DEVICE_PUBLIC_KEY_FOR_TLS pkcs11configLABEL_DEVICE_CERTIFICATE_FOR_TLS +#define pkcs11configLABEL_DEVICE_PUBLIC_KEY_FOR_TLS "device public" #endif /** Standard Configuration Structure for ATECC608 devices */ @@ -185,13 +185,14 @@ CK_RV pkcs11_config_load_objects(pkcs11_slot_ctx_ptr pSlot) CK_RV pkcs11_config_interface(pkcs11_slot_ctx_ptr pSlot) { CK_RV rv = CKR_ARGUMENTS_BAD; + if (pSlot) { #ifdef ATCA_HAL_I2C - cfg_ateccx08a_i2c_default.atcai2c.slave_address = 0xC0; - slot_ctx->interface_config = &cfg_ateccx08a_i2c_default; + cfg_ateccx08a_i2c_default.atcai2c.slave_address = 0xC0; + slot_ctx->interface_config = &cfg_ateccx08a_i2c_default; #else - slot_ctx->interface_config = &cfg_ateccx08a_kithid_default; + slot_ctx->interface_config = &cfg_ateccx08a_kithid_default; #endif } return rv; diff --git a/app/pkcs11/trust_pkcs11_config.c b/app/pkcs11/trust_pkcs11_config.c index 5698df9a1..d3ec207ab 100644 --- a/app/pkcs11/trust_pkcs11_config.c +++ b/app/pkcs11/trust_pkcs11_config.c @@ -38,6 +38,8 @@ const char pkcs11_trust_device_label[] = "device"; const char pkcs11_trust_signer_label[] = "signer"; const char pkcs11_trust_root_label[] = "root"; +const char pkcs11_trust_device_private_key_label[] = "device private"; +const char pkcs11_trust_device_public_key_label[] = "device public"; /* Helper function to assign the proper fields to an certificate object from a cert def */ CK_RV pkcs11_trust_config_cert(pkcs11_lib_ctx_ptr pLibCtx, pkcs11_slot_ctx_ptr pSlot, pkcs11_object_ptr pObject, CK_ATTRIBUTE_PTR pLabel) @@ -100,6 +102,47 @@ CK_RV pkcs11_trust_config_cert(pkcs11_lib_ctx_ptr pLibCtx, pkcs11_slot_ctx_ptr p return rv; } +/* Helper function to assign the proper fields to a key object */ +CK_RV pkcs11_trust_config_key(pkcs11_lib_ctx_ptr pLibCtx, pkcs11_slot_ctx_ptr pSlot, pkcs11_object_ptr pObject, CK_ATTRIBUTE_PTR pLabel) +{ + CK_RV rv = CKR_OK; + + (void)pLibCtx; + + if (!pObject || !pLabel || !pSlot) + { + return CKR_ARGUMENTS_BAD; + } + + if (pLabel->ulValueLen >= PKCS11_MAX_LABEL_SIZE) + { + return CKR_ARGUMENTS_BAD; + } + + if (!strncmp(pkcs11_trust_device_private_key_label, (char*)pLabel->pValue, pLabel->ulValueLen)) + { + /* slot 0 - Device Private Key */ + pkcs11_config_init_private(pObject, pLabel->pValue, pLabel->ulValueLen); + pObject->slot = 0; + pObject->flags |= PKCS11_OBJECT_FLAG_TRUST_TYPE; + pObject->config = &pSlot->cfg_zone; + } + else if (!strncmp(pkcs11_trust_device_public_key_label, (char*)pLabel->pValue, pLabel->ulValueLen)) + { + /* slot 0 - Device Public Key */ + pkcs11_config_init_public(pObject, pLabel->pValue, pLabel->ulValueLen); + pObject->slot = 0; + pObject->flags |= PKCS11_OBJECT_FLAG_TRUST_TYPE; + pObject->config = &pSlot->cfg_zone; + } + else + { + rv = CKR_ARGUMENTS_BAD; + } + + return rv; +} + CK_RV pkcs11_trust_load_objects(pkcs11_slot_ctx_ptr pSlot) { pkcs11_object_ptr pObject; diff --git a/app/tng/tng_atcacert_client.c b/app/tng/tng_atcacert_client.c index 2b4e570e1..21bfa9014 100644 --- a/app/tng/tng_atcacert_client.c +++ b/app/tng/tng_atcacert_client.c @@ -104,6 +104,8 @@ int tng_atcacert_device_public_key(uint8_t* public_key, uint8_t* cert) const atcacert_def_t* cert_def = NULL; uint8_t raw_public_key[72]; + (void)cert; + if (public_key == NULL) { return ATCACERT_E_BAD_PARAMS; diff --git a/cryptoauthlib-manual.pdf b/cryptoauthlib-manual.pdf index 28e166a64..2cfc191db 100644 Binary files a/cryptoauthlib-manual.pdf and b/cryptoauthlib-manual.pdf differ diff --git a/harmony/config/cryptoauthlib.py b/harmony/config/cryptoauthlib.py index c38150671..80e1fd75b 100644 --- a/harmony/config/cryptoauthlib.py +++ b/harmony/config/cryptoauthlib.py @@ -36,6 +36,17 @@ _CORE_PATHS = ['crypto/**/*', 'crypto/*', 'jwt/*', '*'] _CA_PATHS = ['atcacert/*', 'calib/*', 'host/*'] _TA_PATHS = ['talib/*'] +_SHA206_PATHS = ['api_206a/*'] + + +def CALSecFileUpdate(symbol, event): + symObj = event['symbol'] + selected_key = symObj.getSelectedKey() + + if selected_key == "SECURE": + symbol.setSecurity("SECURE") + elif selected_key == "NON_SECURE": + symbol.setSecurity("NON_SECURE") def add_value_to_list(symbol_list, value): @@ -121,6 +132,7 @@ def AddFile(component, src_path, dest_path, proj_path, file_type = "SOURCE", isM srcFile.setOutputName(os.path.basename(src_path)) srcFile.setMarkup(isMarkup) srcFile.setEnabled(enable) + srcFile.setDependencies(CALSecFileUpdate, ["CAL_NON_SECURE"]) numFileCntr += 1 @@ -179,6 +191,8 @@ def onAttachmentConnected(source, target): calTaEnableFce.setValue(True) else: _ca_dev_cnt += 1 + if 'SHA206' in targetComponentID: + updateFileEnable(srcComponent, _SHA206_PATHS, True) updateFileEnable(srcComponent, _CA_PATHS, True) if srcConnectionID == 'FreeRTOS': @@ -221,6 +235,8 @@ def onAttachmentDisconnected(source, target): else: _ca_dev_cnt -= 1 if 0 == _ca_dev_cnt: + if 'SHA206' in targetComponentID: + updateFileEnable(srcComponent, _SHA206_PATHS, False) updateFileEnable(srcComponent, _CA_PATHS, False) @@ -264,6 +280,7 @@ def instantiateComponent(calComponent): defSym.setValue( '{0};{0}/crypto;{0}/pkcs11'.format(targetPath)) defSym.setAppend(True, ';') + defSym.setDependencies(CALSecFileUpdate, ["CAL_NON_SECURE"]) # Add core library files for search_path in _CORE_PATHS: @@ -279,6 +296,10 @@ def instantiateComponent(calComponent): AddFilesDir(calComponent, 'lib', search_path, 'library/cryptoauthlib', 'config/{}/library/cryptoauthlib'.format(configName), enable=False) + for search_path in _SHA206_PATHS: + AddFilesDir(calComponent, 'app', search_path, 'library/cryptoauthlib/app', + 'config/{}/library/cryptoauthlib/app'.format(configName), enable=False) + # Add individual files for hal_file in _HAL_FILES: AddFilesDir(calComponent, 'lib/hal', hal_file, 'library/cryptoauthlib/hal', @@ -321,6 +342,7 @@ def instantiateComponent(calComponent): calLibFreeRTOSSrcFile.setProjectPath("config/" + configName + "/library/cryptoauthlib/hal/") calLibFreeRTOSSrcFile.setType('SOURCE') calLibFreeRTOSSrcFile.setEnabled(False) + calLibFreeRTOSSrcFile.setDependencies(CALSecFileUpdate, ["CAL_NON_SECURE"]) # Replaces cryptoauthlib host functions with WolfCrypto provided ones calEnableWolfCrypto = calComponent.createBooleanSymbol('CAL_ENABLE_WOLFCRYPTO', None) @@ -334,6 +356,7 @@ def instantiateComponent(calComponent): calLibWolfSSLSrcFile.setProjectPath("config/" + configName + "/library/cryptoauthlib/wolfssl/") calLibWolfSSLSrcFile.setType('SOURCE') calLibWolfSSLSrcFile.setEnabled(False) + calLibWolfSSLSrcFile.setDependencies(CALSecFileUpdate, ["CAL_NON_SECURE"]) # Add HAL Drivers calLibI2cHalSrcFile = calComponent.createFileSymbol("CAL_FILE_SRC_HAL_I2C", None) @@ -343,6 +366,7 @@ def instantiateComponent(calComponent): calLibI2cHalSrcFile.setProjectPath("config/" + configName + "/library/cryptoauthlib/hal/") calLibI2cHalSrcFile.setType('SOURCE') calLibI2cHalSrcFile.setEnabled(False) + calLibI2cHalSrcFile.setDependencies(CALSecFileUpdate, ["CAL_NON_SECURE"]) calLibUartHalSrcFile = calComponent.createFileSymbol("CAL_FILE_SRC_HAL_UART", None) calLibUartHalSrcFile.setSourcePath("lib/hal/hal_uart_harmony.c") @@ -351,6 +375,7 @@ def instantiateComponent(calComponent): calLibUartHalSrcFile.setProjectPath("config/" + configName + "/library/cryptoauthlib/hal/") calLibUartHalSrcFile.setType('SOURCE') calLibUartHalSrcFile.setEnabled(False) + calLibUartHalSrcFile.setDependencies(CALSecFileUpdate, ["CAL_NON_SECURE"]) calLibSwiUartHalSrcFile = calComponent.createFileSymbol("CAL_FILE_SRC_HAL_SWI_UART", None) calLibSwiUartHalSrcFile.setSourcePath("lib/hal/hal_swi_uart.c") @@ -359,6 +384,7 @@ def instantiateComponent(calComponent): calLibSwiUartHalSrcFile.setProjectPath("config/" + configName + "/library/cryptoauthlib/hal/") calLibSwiUartHalSrcFile.setType('SOURCE') calLibSwiUartHalSrcFile.setEnabled(False) + calLibSwiUartHalSrcFile.setDependencies(CALSecFileUpdate, ["CAL_NON_SECURE"]) calLibSwiBBHalSrcFile = calComponent.createFileSymbol("CAL_FILE_SRC_HAL_BB", None) calLibSwiBBHalSrcFile.setSourcePath("lib/hal/hal_gpio_harmony.c") @@ -367,6 +393,7 @@ def instantiateComponent(calComponent): calLibSwiBBHalSrcFile.setProjectPath("config/" + configName + "/library/cryptoauthlib/hal/") calLibSwiBBHalSrcFile.setType('SOURCE') calLibSwiBBHalSrcFile.setEnabled(False) + calLibSwiBBHalSrcFile.setDependencies(CALSecFileUpdate, ["CAL_NON_SECURE"]) calLibSwiBBHalSrcFile = calComponent.createFileSymbol("CAL_FILE_SRC_HAL_SWI_BB", None) calLibSwiBBHalSrcFile.setSourcePath("lib/hal/hal_swi_bitbang_harmony.c") @@ -375,6 +402,7 @@ def instantiateComponent(calComponent): calLibSwiBBHalSrcFile.setProjectPath("config/" + configName + "/library/cryptoauthlib/hal/") calLibSwiBBHalSrcFile.setType('SOURCE') calLibSwiBBHalSrcFile.setEnabled(False) + calLibSwiBBHalSrcFile.setDependencies(CALSecFileUpdate, ["CAL_NON_SECURE"]) calLibSpiHalSrcFile = calComponent.createFileSymbol("CAL_FILE_SRC_HAL_SPI", None) calLibSpiHalSrcFile.setSourcePath("lib/hal/hal_spi_harmony.c") @@ -383,6 +411,7 @@ def instantiateComponent(calComponent): calLibSpiHalSrcFile.setProjectPath("config/" + configName + "/library/cryptoauthlib/hal/") calLibSpiHalSrcFile.setType('SOURCE') calLibSpiHalSrcFile.setEnabled(False) + calLibSpiHalSrcFile.setDependencies(CALSecFileUpdate, ["CAL_NON_SECURE"]) # List of HALs that will be included based on device connections calHalList = calComponent.createListSymbol('CAL_HAL_LIST', None) @@ -419,6 +448,7 @@ def instantiateComponent(calComponent): calLibCoreM0PlusSrcFile.setType("SOURCE") calLibCoreM0PlusSrcFile.setOverwrite(True) calLibCoreM0PlusSrcFile.setMarkup(True) + calLibCoreM0PlusSrcFile.setDependencies(CALSecFileUpdate, ["CAL_NON_SECURE"]) # Configuration header file calLibConfigFile = calComponent.createFileSymbol("CAL_LIB_CONFIG_DATA", None) @@ -429,6 +459,7 @@ def instantiateComponent(calComponent): calLibConfigFile.setType("HEADER") calLibConfigFile.setOverwrite(True) calLibConfigFile.setMarkup(True) + calLibConfigFile.setDependencies(CALSecFileUpdate, ["CAL_NON_SECURE"]) # This selects and configures the proper processor specific delay implementation as one @@ -446,6 +477,14 @@ def instantiateComponent(calComponent): calLibDelaySrcFile.setType("SOURCE") calLibDelaySrcFile.setOverwrite(True) calLibDelaySrcFile.setMarkup(True) - - - + calLibDelaySrcFile.setDependencies(CALSecFileUpdate, ["CAL_NON_SECURE"]) + + if Variables.get("__TRUSTZONE_ENABLED") != None and Variables.get("__TRUSTZONE_ENABLED") == "true": + calSecurity = calComponent.createKeyValueSetSymbol("CAL_NON_SECURE", None) + calSecurity.setLabel("Security mode") + calSecurity.addKey("NON_SECURE", "0", "False") + calSecurity.addKey("SECURE", "1", "True") + calSecurity.setOutputMode("Key") + calSecurity.setDisplayMode("Key") + calSecurity.setVisible(True) + calSecurity.setDefaultValue(0) diff --git a/harmony/config/device_instance.py b/harmony/config/device_instance.py index 8afc5076b..5920600bd 100644 --- a/harmony/config/device_instance.py +++ b/harmony/config/device_instance.py @@ -28,6 +28,16 @@ _SPI_DEVICES = ['TA100'] +def CALSecFileUpdate(symbol, event): + symObj = event['symbol'] + selected_key = symObj.getSelectedKey() + + if selected_key == "SECURE": + symbol.setSecurity("SECURE") + elif selected_key == "NON_SECURE": + symbol.setSecurity("NON_SECURE") + + def updateSercomPlibList(plib, inc): Database.sendMessage('cryptoauthlib', 'UPDATE_PLIB_LIST', {'id': plib.lower(), 'inc': inc}) @@ -211,6 +221,13 @@ def instantiateComponent(deviceComponent, index): devInitDataFile.setType('SOURCE') devInitDataFile.setOverwrite(True) devInitDataFile.setMarkup(True) + try: + CALSecValue = Database.getComponentByID('cryptoauthlib').getSymbolByID('CAL_NON_SECURE').getValue() + if CALSecValue == True: + devInitDataFile.setSecurity("SECURE") + except: + pass + devInitDataFile.setDependencies(CALSecFileUpdate, ["cryptoauthlib.CAL_NON_SECURE"]) def onAttachmentConnected(source, target): diff --git a/harmony/config/pkcs11.py b/harmony/config/pkcs11.py index c30d55b7a..b597cffea 100644 --- a/harmony/config/pkcs11.py +++ b/harmony/config/pkcs11.py @@ -29,6 +29,16 @@ _tng_type_tracker = {} +def CALSecFileUpdate(symbol, event): + symObj = event['symbol'] + selected_key = symObj.getSelectedKey() + + if selected_key == "SECURE": + symbol.setSecurity("SECURE") + elif selected_key == "NON_SECURE": + symbol.setSecurity("NON_SECURE") + + def AddFile(component, src_path, dest_path, proj_path, file_type = "SOURCE", isMarkup = False): global fileSymbolName global numFileCntr @@ -39,6 +49,13 @@ def AddFile(component, src_path, dest_path, proj_path, file_type = "SOURCE", isM srcFile.setType(file_type) srcFile.setOutputName(os.path.basename(src_path)) srcFile.setMarkup(isMarkup) + try: + CALSecValue = Database.getComponentByID('cryptoauthlib').getSymbolByID('CAL_NON_SECURE').getValue() + if CALSecValue == True: + srcFile.setSecurity("SECURE") + except: + pass + srcFile.setDependencies(CALSecFileUpdate, ["cryptoauthlib.CAL_NON_SECURE"]) numFileCntr += 1 @@ -80,6 +97,13 @@ def instantiateComponent(calPkcs11Component): calPkcs11TngFile.setProjectPath("config/" + configName + "/library/cryptoauthlib/app/pkcs11") calPkcs11TngFile.setType('SOURCE') calPkcs11TngFile.setEnabled(True) + try: + CALSecValue = Database.getComponentByID('cryptoauthlib').getSymbolByID('CAL_NON_SECURE').getValue() + if CALSecValue == True: + calPkcs11TngFile.setSecurity("SECURE") + except: + pass + calPkcs11TngFile.setDependencies(CALSecFileUpdate, ["cryptoauthlib.CAL_NON_SECURE"]) # Configuration options for the PKCS11 module calPkcs11ExternalFuncList = calPkcs11Component.createBooleanSymbol("CAL_PKCS11_EXT_FUNC_LIST", None) @@ -90,7 +114,7 @@ def instantiateComponent(calPkcs11Component): calPkcs11DebugPrint = calPkcs11Component.createBooleanSymbol("CAL_PKCS11_ENABLE_DEBUG_PRINT", None) calPkcs11DebugPrint.setLabel("Enable Debug Print?") calPkcs11DebugPrint.setDefaultValue(False) - + calPkcs11AwsFreeRTOS = calPkcs11Component.createBooleanSymbol("CAL_PKCS11_AWS_FREERTOS", None) calPkcs11AwsFreeRTOS.setLabel("Enable AWS FreeRTOS Modifications?") calPkcs11AwsFreeRTOS.setDefaultValue(False) @@ -120,6 +144,10 @@ def instantiateComponent(calPkcs11Component): pkcs11ConfigFile.setType("HEADER") pkcs11ConfigFile.setOverwrite(True) pkcs11ConfigFile.setMarkup(True) - - - + try: + CALSecValue = Database.getComponentByID('cryptoauthlib').getSymbolByID('CAL_NON_SECURE').getValue() + if CALSecValue == True: + pkcs11ConfigFile.setSecurity("SECURE") + except: + pass + pkcs11ConfigFile.setDependencies(CALSecFileUpdate, ["cryptoauthlib.CAL_NON_SECURE"]) diff --git a/harmony/config/test_app.py b/harmony/config/test_app.py index 116735548..4147d2d21 100644 --- a/harmony/config/test_app.py +++ b/harmony/config/test_app.py @@ -27,12 +27,22 @@ fileSymbolName = "CAL_FILE_SRC_TEST_" numFileCntr = 0 -_TEST_PATHS = ['atcacert/*', 'jwt/*', 'api_atcab/*', 'api_calib/*', 'api_talib/*', 'vectors/*'] +_TEST_PATHS = ['atcacert/*', 'jwt/*', 'api_atcab/*', 'api_calib/*', 'api_crypto', 'api_talib/*', 'vectors/*'] _TEST_SOURCES = ['atca_crypto_sw_tests.c', 'atca_test.c', 'atca_test_config.c', 'atca_test_console.c', 'atca_utils_atecc608.c', 'cmd-processor.c'] _TEST_HEADERS = ['atca_crypto_sw_tests.h', 'atca_test.h', 'cbuf.h', 'cmd-processor.h'] +def CALSecFileUpdate(symbol, event): + symObj = event['symbol'] + selected_key = symObj.getSelectedKey() + + if selected_key == "SECURE": + symbol.setSecurity("SECURE") + elif selected_key == "NON_SECURE": + symbol.setSecurity("NON_SECURE") + + def AddFile(component, src_path, dest_path, proj_path, file_type = "SOURCE", isMarkup = False, enable=True): global fileSymbolName global numFileCntr @@ -44,6 +54,13 @@ def AddFile(component, src_path, dest_path, proj_path, file_type = "SOURCE", isM srcFile.setOutputName(os.path.basename(src_path)) srcFile.setMarkup(isMarkup) srcFile.setEnabled(enable) + try: + CALSecValue = Database.getComponentByID('cryptoauthlib').getSymbolByID('CAL_NON_SECURE').getValue() + if CALSecValue == True: + srcFile.setSecurity("SECURE") + except: + pass + srcFile.setDependencies(CALSecFileUpdate, ["cryptoauthlib.CAL_NON_SECURE"]) numFileCntr += 1 @@ -86,6 +103,13 @@ def instantiateComponent(calTestingApplication): defSym.setValue('{0}/test'.format(targetPath)) defSym.setAppend(True, ';') + try: + CALSecValue = Database.getComponentByID('cryptoauthlib').getSymbolByID('CAL_NON_SECURE').getValue() + if CALSecValue == True: + defSym.setSecurity("SECURE") + except: + pass + defSym.setDependencies(CALSecFileUpdate, ["cryptoauthlib.CAL_NON_SECURE"]) # Add core library files diff --git a/harmony/config/tng.py b/harmony/config/tng.py index adc88a52a..ee1bf78db 100644 --- a/harmony/config/tng.py +++ b/harmony/config/tng.py @@ -29,6 +29,16 @@ _tng_type_tracker = {} +def CALSecFileUpdate(symbol, event): + symObj = event['symbol'] + selected_key = symObj.getSelectedKey() + + if selected_key == "SECURE": + symbol.setSecurity("SECURE") + elif selected_key == "NON_SECURE": + symbol.setSecurity("NON_SECURE") + + def updateTracker(id, src): global _tng_type_tracker _tng_type_tracker[src] = id @@ -62,6 +72,13 @@ def AddFile(component, src_path, dest_path, proj_path, file_type = "SOURCE", isM srcFile.setType(file_type) srcFile.setOutputName(os.path.basename(src_path)) srcFile.setMarkup(isMarkup) + try: + CALSecValue = Database.getComponentByID('cryptoauthlib').getSymbolByID('CAL_NON_SECURE').getValue() + if CALSecValue == True: + srcFile.setSecurity("SECURE") + except: + pass + srcFile.setDependencies(CALSecFileUpdate, ["cryptoauthlib.CAL_NON_SECURE"]) numFileCntr += 1 def AddFilesDir(component, configName, dirPath): @@ -91,6 +108,17 @@ def instantiateComponent(tngComponent): Database.activateComponents(['cryptoauthlib']) configName = Variables.get("__CONFIGURATION_NAME") + + targetPath = '../src/config/' + configName + '/library/cryptoauthlib/tng' + + # Append the include paths in MPLABX IDE + defSym = tngComponent.createSettingSymbol("CAL_XC32_INCLUDE_DIRS", None) + defSym.setCategory("C32") + defSym.setKey("extra-include-directories") + + defSym.setValue( '{0}'.format(targetPath)) + defSym.setAppend(True, ';') + defSym.setDependencies(CALSecFileUpdate, ["CAL_NON_SECURE"]) AddFilesDir(tngComponent, configName, 'app/tng') diff --git a/harmony/module.py b/harmony/module.py index a85e19e00..815d67242 100644 --- a/harmony/module.py +++ b/harmony/module.py @@ -53,7 +53,8 @@ def loadModule(): for dev in _CALIB_SUPPORTED_DEVICES: comp = Module.CreateGeneratorComponent(dev.lower(), dev, "/Harmony/Drivers/Crypto", "/harmony/config/device_common.py", "/harmony/config/device_instance.py") comp.addDependency("cryptoauthlib", "CA_LIB", True, False) - comp.addMultiDependency('{}_DEP_PLIB_I2C'.format(dev.upper()), 'I2C', 'I2C', False) + if 'ATSHA206A' not in dev: + comp.addMultiDependency('{}_DEP_PLIB_I2C'.format(dev.upper()), 'I2C', 'I2C', False) comp.addMultiDependency('{}_DEP_PLIB_SWI'.format(dev.upper()), 'UART', 'SWI', False) if os.path.exists(Module.getPath() + 'lib/talib/talib_basic.h'): diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 69657eb28..254c43434 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -109,7 +109,9 @@ execute_process(COMMAND ${CMAKE_COMMAND} --build . WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/${DEPENDENCY_DIR}/mbedtls_downloader/) file(GLOB MBEDTLS_LIB_SRC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "../third_party/mbedtls/library/*.c") + add_library(mbedtls STATIC ${MBEDTLS_LIB_SRC}) + target_compile_definitions(mbedtls PUBLIC -DMBEDTLS_CMAC_C) if(NOT WIN32) target_compile_options(mbedtls PRIVATE -fPIC) @@ -119,9 +121,13 @@ include_directories(mbedtls PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} endif() file(GLOB MBEDTLS_SRC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "mbedtls/*.c") + if(${CMAKE_VERSION} VERSION_GREATER "3.8.0") source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${MBEDTLS_SRC}) endif() + +set(MBEDTLS_SRC ${MBEDTLS_SRC} "../third_party/atca_mbedtls_patch.c") + endif(ATCA_MBEDTLS) if (ATCA_WOLFSSL) @@ -139,7 +145,7 @@ set(WOLFSSL_LIB_SRC ../third_party/wolfssl/wolfcrypt/src/aes.c ../third_party/wolfssl/wolfcrypt/src/cmac.c ../third_party/wolfssl/wolfcrypt/src/coding.c ../third_party/wolfssl/wolfcrypt/src/des3.c - ../third_party/wolfssl/wolfcrypt/src/ecc.c + ../third_party/wolfssl/wolfcrypt/src/ecc.c ../third_party/wolfssl/wolfcrypt/src/hash.c ../third_party/wolfssl/wolfcrypt/src/hmac.c ../third_party/wolfssl/wolfcrypt/src/integer.c @@ -322,7 +328,7 @@ configure_file(pkcs11/pkcs11_config.h.in pkcs11_config.h @ONLY) set(PKCS11_INC ${PKCS11_INC} ${CMAKE_CURRENT_BINARY_DIR}/pkcs11_config.h) endif() -include_directories(cryptoauth PUBLIC ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ../app/tng ../third_party/hidapi/hidapi ${USB_INCLUDE_DIR}) +include_directories(cryptoauth PUBLIC ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ../app/tng ../third_party ../third_party/hidapi/hidapi ${USB_INCLUDE_DIR}) if(ATCA_MBEDTLS) target_link_libraries(cryptoauth mbedtls) diff --git a/lib/atca_basic.c b/lib/atca_basic.c index 58308e662..f63b0bb7f 100644 --- a/lib/atca_basic.c +++ b/lib/atca_basic.c @@ -2273,6 +2273,47 @@ ATCA_STATUS atcab_is_slot_locked(uint16_t slot, bool* is_locked) return status; } + +/** \brief Check to see if the key is a private key or not + * + * This function will issue the Read command as many times as is required to + * read the requested data. + * + * \param[in] slot Slot number to read from if zone is ATCA_ZONE_DATA(2). + * Ignored for all other zones. + * \param[out] is_private Returned valud if successful. True if key is private. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_is_private_ext(ATCADevice device, uint16_t slot, bool* is_private) +{ + ATCA_STATUS status = ATCA_UNIMPLEMENTED; + ATCADeviceType dev_type = atcab_get_device_type_ext(device); + + if (atcab_is_ca_device(dev_type)) + { +#if ATCA_CA_SUPPORT + status = calib_is_private(_gDevice, slot, is_private); +#endif + } + else if (atcab_is_ta_device(dev_type)) + { +#if ATCA_TA_SUPPORT + status = talib_is_private(_gDevice, slot, is_private); +#endif + } + else + { + status = ATCA_NOT_INITIALIZED; + } + return status; +} + +ATCA_STATUS atcab_is_private(uint16_t slot, bool* is_private) +{ + return atcab_is_private_ext(_gDevice, slot, is_private); +} + /** \brief Used to read an arbitrary number of bytes from any zone configured * for clear reads. * @@ -2367,6 +2408,7 @@ ATCA_STATUS atcab_read_serial_number(uint8_t* serial_number) * This function assumes the public key is stored using the ECC public key * format specified in the datasheet. * + * \param[in] device Device context pointer * \param[in] slot Slot number to read from. Only slots 8 to 15 are * large enough for a public key. * \param[out] public_key Public key is returned here (64 bytes). Format will @@ -2375,10 +2417,10 @@ ATCA_STATUS atcab_read_serial_number(uint8_t* serial_number) * * \return ATCA_SUCCESS on success, otherwise an error code. */ -ATCA_STATUS atcab_read_pubkey(uint16_t slot, uint8_t* public_key) +ATCA_STATUS atcab_read_pubkey_ext(ATCADevice device, uint16_t slot, uint8_t* public_key) { ATCA_STATUS status = ATCA_UNIMPLEMENTED; - ATCADeviceType dev_type = atcab_get_device_type(); + ATCADeviceType dev_type = atcab_get_device_type_ext(device); if (atcab_is_ca_device(dev_type)) { @@ -2399,6 +2441,25 @@ ATCA_STATUS atcab_read_pubkey(uint16_t slot, uint8_t* public_key) return status; } +/** \brief Executes Read command to read an ECC P256 public key from a slot + * configured for clear reads. + * + * This function assumes the public key is stored using the ECC public key + * format specified in the datasheet. + * + * \param[in] slot Slot number to read from. Only slots 8 to 15 are + * large enough for a public key. + * \param[out] public_key Public key is returned here (64 bytes). Format will + * be the 32 byte X and Y big-endian integers + * concatenated. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_read_pubkey(uint16_t slot, uint8_t* public_key) +{ + return atcab_read_pubkey_ext(_gDevice, slot, public_key); +} + /** \brief Executes Read command to read a 64 byte ECDSA P256 signature from a * slot configured for clear reads. * @@ -3136,8 +3197,11 @@ ATCA_STATUS atcab_sha_hmac_finish(atca_hmac_sha256_ctx_t* ctx, uint8_t* digest, return status; } + + /** \brief Use the SHA command to compute an HMAC/SHA-256 operation. * + * \param[in] device Device context pointer * \param[in] data Message data to be hashed. * \param[in] data_size Size of data in bytes. * \param[in] key_slot Slot key id to use for the HMAC calculation @@ -3150,21 +3214,21 @@ ATCA_STATUS atcab_sha_hmac_finish(atca_hmac_sha256_ctx_t* ctx, uint8_t* digest, * * \return ATCA_SUCCESS on success, otherwise an error code. */ -ATCA_STATUS atcab_sha_hmac(const uint8_t* data, size_t data_size, uint16_t key_slot, uint8_t* digest, uint8_t target) +ATCA_STATUS atcab_sha_hmac_ext(ATCADevice device, const uint8_t* data, size_t data_size, uint16_t key_slot, uint8_t* digest, uint8_t target) { ATCA_STATUS status = ATCA_UNIMPLEMENTED; - ATCADeviceType dev_type = atcab_get_device_type(); + ATCADeviceType dev_type = atcab_get_device_type_ext(device); if (atcab_is_ca_device(dev_type)) { #if ATCA_CA_SUPPORT - status = calib_sha_hmac(_gDevice, data, data_size, key_slot, digest, target); + status = calib_sha_hmac(device, data, data_size, key_slot, digest, target); #endif } else if (atcab_is_ta_device(dev_type)) { #if ATCA_TA_SUPPORT - status = talib_hmac_compat(_gDevice, data, data_size, key_slot, digest, target); + status = talib_hmac_compat(device, data, data_size, key_slot, digest, target); #endif } else @@ -3174,6 +3238,25 @@ ATCA_STATUS atcab_sha_hmac(const uint8_t* data, size_t data_size, uint16_t key_s return status; } +/** \brief Use the SHA command to compute an HMAC/SHA-256 operation. + * + * \param[in] data Message data to be hashed. + * \param[in] data_size Size of data in bytes. + * \param[in] key_slot Slot key id to use for the HMAC calculation + * \param[out] digest Digest is returned here (32 bytes). + * \param[in] target Where to save the digest internal to the device. + * For ATECC608, can be SHA_MODE_TARGET_TEMPKEY, + * SHA_MODE_TARGET_MSGDIGBUF, or + * SHA_MODE_TARGET_OUT_ONLY. For all other devices, + * SHA_MODE_TARGET_TEMPKEY is the only option. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_sha_hmac(const uint8_t* data, size_t data_size, uint16_t key_slot, uint8_t* digest, uint8_t target) +{ + return atcab_sha_hmac_ext(_gDevice, data, data_size, key_slot, digest, target); +} + /* Sign command */ @@ -3238,19 +3321,19 @@ ATCA_STATUS atcab_sign_ext(ATCADevice device, uint16_t key_id, const uint8_t* ms if (ECC204 == dev_type) { #if defined(ATCA_ECC204_SUPPORT) - status = calib_ecc204_sign(_gDevice, key_id, msg, signature); + status = calib_ecc204_sign(device, key_id, msg, signature); #endif } else { - status = calib_sign(_gDevice, key_id, msg, signature); + status = calib_sign(device, key_id, msg, signature); } #endif } else if (atcab_is_ta_device(dev_type)) { #if ATCA_TA_SUPPORT - status = talib_sign_compat(_gDevice, key_id, msg, signature); + status = talib_sign_compat(device, key_id, msg, signature); #endif } else diff --git a/lib/atca_basic.h b/lib/atca_basic.h index f23713c21..88911d610 100644 --- a/lib/atca_basic.h +++ b/lib/atca_basic.h @@ -103,6 +103,9 @@ ATCA_STATUS atcab_aes_ccm_decrypt_update(atca_aes_ccm_ctx_t* ctx, const uint8_t* ATCA_STATUS atcab_aes_ccm_encrypt_finish(atca_aes_ccm_ctx_t* ctx, uint8_t* tag, uint8_t* tag_size); ATCA_STATUS atcab_aes_ccm_decrypt_finish(atca_aes_ccm_ctx_t* ctx, const uint8_t* tag, bool* is_verified); +// Hardware Accelerated algorithms +ATCA_STATUS atcab_pbkdf2_sha256_ext(ATCADevice device, const uint32_t iter, const uint16_t slot, const uint8_t* salt, const size_t salt_len, uint8_t* result, size_t result_len); +ATCA_STATUS atcab_pbkdf2_sha256(const uint32_t iter, const uint16_t slot, const uint8_t* salt, const size_t salt_len, uint8_t* result, size_t result_len); #if ATCA_CA_SUPPORT && !ATCA_TA_SUPPORT && !defined(ATCA_USE_ATCAB_FUNCTIONS) && !defined(ATCA_ECC204_SUPPORT) @@ -203,9 +206,12 @@ ATCA_STATUS atcab_aes_ccm_decrypt_finish(atca_aes_ccm_ctx_t* ctx, const uint8_t* #define atcab_is_config_locked(...) calib_is_locked(_gDevice, LOCK_ZONE_CONFIG, __VA_ARGS__) #define atcab_is_data_locked(...) calib_is_locked(_gDevice, LOCK_ZONE_DATA, __VA_ARGS__) #define atcab_is_slot_locked(...) calib_is_slot_locked(_gDevice, __VA_ARGS__) +#define atcab_is_private(...) calib_is_private(_gDevice, __VA_ARGS__) +#define atcab_is_private_ext calib_is_private #define atcab_read_bytes_zone(...) calib_read_bytes_zone(_gDevice, __VA_ARGS__) #define atcab_read_serial_number(...) calib_read_serial_number(_gDevice, __VA_ARGS__) #define atcab_read_pubkey(...) calib_read_pubkey(_gDevice, __VA_ARGS__) +#define atcab_read_pubkey_ext calib_read_pubkey #define atcab_read_sig(...) calib_read_sig(_gDevice, __VA_ARGS__) #define atcab_read_config_zone(...) calib_read_config_zone(_gDevice, __VA_ARGS__) #define atcab_cmp_config_zone(...) calib_cmp_config_zone(_gDevice, __VA_ARGS__) @@ -235,6 +241,7 @@ ATCA_STATUS atcab_aes_ccm_decrypt_finish(atca_aes_ccm_ctx_t* ctx, const uint8_t* #define atcab_sha_hmac_update(...) calib_sha_hmac_update(_gDevice, __VA_ARGS__) #define atcab_sha_hmac_finish(...) calib_sha_hmac_finish(_gDevice, __VA_ARGS__) #define atcab_sha_hmac(...) calib_sha_hmac(_gDevice, __VA_ARGS__) +#define atcab_sha_hmac_ext calib_sha_hmac #define SHA_CONTEXT_MAX_SIZE (99) // Sign command functions @@ -365,9 +372,12 @@ ATCA_STATUS atcab_aes_ccm_decrypt_finish(atca_aes_ccm_ctx_t* ctx, const uint8_t* #define atcab_is_config_locked(...) talib_is_config_locked(_gDevice, __VA_ARGS__) #define atcab_is_data_locked(...) talib_is_setup_locked(_gDevice, __VA_ARGS__) #define atcab_is_slot_locked(...) talib_is_handle_locked(_gDevice, __VA_ARGS__) +#define atcab_is_private(...) talib_is_private(_gDevice, __VA_ARGS__) +#define atcab_is_private_ext talib_is_private #define atcab_read_bytes_zone(...) talib_read_bytes_zone(_gDevice, __VA_ARGS__) #define atcab_read_serial_number(...) talib_info_serial_number_compat(_gDevice, __VA_ARGS__) #define atcab_read_pubkey(...) talib_read_pubkey_compat(_gDevice, __VA_ARGS__) +#define atcab_read_pubkey_ext talib_read_pubkey_compat #define atcab_read_sig(...) talib_read_sig_compat(_gDevice, __VA_ARGS__) #define atcab_read_config_zone(...) talib_read_config_zone(_gDevice, __VA_ARGS__) #define atcab_cmp_config_zone(...) talib_cmp_config_zone(_gDevice, __VA_ARGS__) @@ -397,6 +407,7 @@ ATCA_STATUS atcab_aes_ccm_decrypt_finish(atca_aes_ccm_ctx_t* ctx, const uint8_t* #define atcab_sha_hmac_update(...) (ATCA_UNIMPLEMENTED) #define atcab_sha_hmac_finish(...) (ATCA_UNIMPLEMENTED) #define atcab_sha_hmac(...) talib_hmac_compat(_gDevice, __VA_ARGS__) +#define atcab_sha_hmac_ext talib_hmac_compat #define SHA_CONTEXT_MAX_SIZE (109) // Sign command functions @@ -540,9 +551,12 @@ ATCA_STATUS atcab_is_locked(uint8_t zone, bool* is_locked); ATCA_STATUS atcab_is_config_locked(bool* is_locked); ATCA_STATUS atcab_is_data_locked(bool* is_locked); ATCA_STATUS atcab_is_slot_locked(uint16_t slot, bool* is_locked); +ATCA_STATUS atcab_is_private_ext(ATCADevice device, uint16_t slot, bool* is_private); +ATCA_STATUS atcab_is_private(uint16_t slot, bool* is_private); ATCA_STATUS atcab_read_bytes_zone(uint8_t zone, uint16_t slot, size_t offset, uint8_t* data, size_t length); ATCA_STATUS atcab_read_serial_number(uint8_t* serial_number); ATCA_STATUS atcab_read_pubkey(uint16_t slot, uint8_t* public_key); +ATCA_STATUS atcab_read_pubkey_ext(ATCADevice device, uint16_t slot, uint8_t* public_key); ATCA_STATUS atcab_read_sig(uint16_t slot, uint8_t* sig); ATCA_STATUS atcab_read_config_zone(uint8_t* config_data); ATCA_STATUS atcab_cmp_config_zone(uint8_t* config_data, bool* same_config); @@ -579,6 +593,7 @@ ATCA_STATUS atcab_sha_hmac_update(atca_hmac_sha256_ctx_t* ctx, const uint8_t* da ATCA_STATUS atcab_sha_hmac_finish(atca_hmac_sha256_ctx_t* ctx, uint8_t* digest, uint8_t target); ATCA_STATUS atcab_sha_hmac(const uint8_t* data, size_t data_size, uint16_t key_slot, uint8_t* digest, uint8_t target); +ATCA_STATUS atcab_sha_hmac_ext(ATCADevice device, const uint8_t* data, size_t data_size, uint16_t key_slot, uint8_t* digest, uint8_t target); /* Sign command */ ATCA_STATUS atcab_sign_base(uint8_t mode, uint16_t key_id, uint8_t* signature); diff --git a/lib/atca_device.h b/lib/atca_device.h index ea9a60e20..a9ac7f262 100644 --- a/lib/atca_device.h +++ b/lib/atca_device.h @@ -283,6 +283,7 @@ ATCAIface atGetIFace(ATCADevice dev); #define ATCA_CHIP_OPT_IO_PROT_KEY(v) (ATCA_CHIP_OPT_IO_PROT_KEY_MASK & (v << ATCA_CHIP_OPT_IO_PROT_KEY_SHIFT)) /* Key Config */ +#define ATCA_KEY_CONFIG_OFFSET(x) (96UL + (x) * 2) #define ATCA_KEY_CONFIG_PRIVATE_SHIFT (0) #define ATCA_KEY_CONFIG_PRIVATE_MASK (0x01u << ATCA_KEY_CONFIG_PRIVATE_SHIFT) #define ATCA_KEY_CONFIG_PUB_INFO_SHIFT (1) diff --git a/lib/atca_iface.c b/lib/atca_iface.c index 617cf087a..d2a72cc33 100644 --- a/lib/atca_iface.c +++ b/lib/atca_iface.c @@ -388,7 +388,9 @@ ATCA_STATUS releaseATCAIface(ATCAIface ca_iface) } if (ATCA_CUSTOM_IFACE == ca_iface->mIfaceCFG->iface_type) { +#ifndef ATCA_NO_HEAP hal_free(ca_iface->hal); +#endif ca_iface->hal = NULL; } } diff --git a/lib/atca_version.h b/lib/atca_version.h index f46f169a1..9b6dc5c3d 100644 --- a/lib/atca_version.h +++ b/lib/atca_version.h @@ -30,9 +30,9 @@ #define _ATCA_VERSION_H // Version format yyyymmdd -#define ATCA_LIBRARY_VERSION_DATE "20210126" +#define ATCA_LIBRARY_VERSION_DATE "20210423" #define ATCA_LIBRARY_VERSION_MAJOR 3 #define ATCA_LIBRARY_VERSION_MINOR 3 -#define ATCA_LIBRARY_VERSION_BUILD 0 +#define ATCA_LIBRARY_VERSION_BUILD 1 #endif /* _ATCA_VERSION_H */ diff --git a/lib/atcacert/atcacert_client.c b/lib/atcacert/atcacert_client.c index f6821c565..c8a03dfc5 100644 --- a/lib/atcacert/atcacert_client.c +++ b/lib/atcacert/atcacert_client.c @@ -256,7 +256,7 @@ int atcacert_create_csr_pem(const atcacert_def_t* csr_def, char* csr, size_t* cs // Create DER CSR csr_der_size = csr_max_size; - status = atcacert_create_csr(csr_def, (uint8_t*)csr, &csr_der_size); + status = (ATCA_STATUS)atcacert_create_csr(csr_def, (uint8_t*)csr, &csr_der_size); if (status != ATCACERT_E_SUCCESS) { return status; @@ -267,7 +267,7 @@ int atcacert_create_csr_pem(const atcacert_def_t* csr_def, char* csr, size_t* cs memmove(csr + (csr_max_size - csr_der_size), csr, csr_der_size); *csr_size = csr_max_size; - status = atcacert_encode_pem_csr((uint8_t*)(csr + (csr_max_size - csr_der_size)), csr_der_size, csr, csr_size); + status = (ATCA_STATUS)atcacert_encode_pem_csr((uint8_t*)(csr + (csr_max_size - csr_der_size)), csr_der_size, csr, csr_size); if (status != ATCACERT_E_SUCCESS) { return status; @@ -293,13 +293,13 @@ int atcacert_create_csr(const atcacert_def_t* csr_def, uint8_t* csr, size_t* csr // Check the pointers if (csr_def == NULL || csr == NULL || csr == NULL || csr_size == NULL) { - status = ATCACERT_E_BAD_PARAMS; + status = (ATCA_STATUS)ATCACERT_E_BAD_PARAMS; ATCA_TRACE(status, "Null input parameter"); break; } // Check the csr buffer size if (*csr_size < csr_def->cert_template_size) { - status = ATCACERT_E_BUFFER_TOO_SMALL; + status = (ATCA_STATUS)ATCACERT_E_BUFFER_TOO_SMALL; ATCA_TRACE(status, "CSR buffer size too small"); break; } // Copy the CSR template into the CSR that will be returned @@ -333,14 +333,14 @@ int atcacert_create_csr(const atcacert_def_t* csr_def, uint8_t* csr, size_t* csr } } // Insert the public key into the CSR template - status = atcacert_set_cert_element(csr_def, pub_loc, csr, *csr_size, pub_key, ATCA_PUB_KEY_SIZE); + status = (ATCA_STATUS)atcacert_set_cert_element(csr_def, pub_loc, csr, *csr_size, pub_key, ATCA_PUB_KEY_SIZE); if (status != ATCA_SUCCESS) { ATCA_TRACE(status, "Setting CSR public key failed"); break; } // Get the CSR TBS digest - status = atcacert_get_tbs_digest(csr_def, csr, *csr_size, tbs_digest); + status = (ATCA_STATUS)atcacert_get_tbs_digest(csr_def, csr, *csr_size, tbs_digest); if (status != ATCA_SUCCESS) { ATCA_TRACE(status, "Get TBS digest failed"); break; @@ -354,7 +354,7 @@ int atcacert_create_csr(const atcacert_def_t* csr_def, uint8_t* csr, size_t* csr } // Insert the signature into the CSR template - status = atcacert_set_signature(csr_def, csr, csr_size, csr_max_size, sig); + status = (ATCA_STATUS)atcacert_set_signature(csr_def, csr, csr_size, csr_max_size, sig); if (status != ATCA_SUCCESS) { ATCA_TRACE(status, "Setting CSR signature failed"); break; diff --git a/lib/atcacert/atcacert_date.c b/lib/atcacert/atcacert_date.c index 51c7e289f..aca8b4c5c 100644 --- a/lib/atcacert/atcacert_date.c +++ b/lib/atcacert/atcacert_date.c @@ -42,7 +42,7 @@ int atcacert_date_enc(atcacert_date_format_t format, uint8_t* formatted_date, size_t* formatted_date_size) { - if (timestamp == NULL || formatted_date_size == NULL || format < 0 || format >= sizeof(ATCACERT_DATE_FORMAT_SIZES) / sizeof(ATCACERT_DATE_FORMAT_SIZES[0])) + if (timestamp == NULL || formatted_date_size == NULL || format >= sizeof(ATCACERT_DATE_FORMAT_SIZES) / sizeof(ATCACERT_DATE_FORMAT_SIZES[0])) { return ATCACERT_E_BAD_PARAMS; } @@ -65,7 +65,7 @@ int atcacert_date_enc(atcacert_date_format_t format, case DATEFMT_POSIX_UINT32_BE: return atcacert_date_enc_posix_uint32_be(timestamp, formatted_date); case DATEFMT_POSIX_UINT32_LE: return atcacert_date_enc_posix_uint32_le(timestamp, formatted_date); case DATEFMT_RFC5280_GEN: return atcacert_date_enc_rfc5280_gen(timestamp, formatted_date); - default: return ATCACERT_E_BAD_PARAMS; + default: break; } return ATCACERT_E_BAD_PARAMS; @@ -76,7 +76,7 @@ int atcacert_date_dec(atcacert_date_format_t format, size_t formatted_date_size, atcacert_tm_utc_t* timestamp) { - if (formatted_date == NULL || timestamp == NULL || format < 0 || format >= sizeof(ATCACERT_DATE_FORMAT_SIZES) / sizeof(ATCACERT_DATE_FORMAT_SIZES[0])) + if (formatted_date == NULL || timestamp == NULL || format >= sizeof(ATCACERT_DATE_FORMAT_SIZES) / sizeof(ATCACERT_DATE_FORMAT_SIZES[0])) { return ATCACERT_E_BAD_PARAMS; } @@ -93,16 +93,16 @@ int atcacert_date_dec(atcacert_date_format_t format, case DATEFMT_POSIX_UINT32_BE: return atcacert_date_dec_posix_uint32_be(formatted_date, timestamp); case DATEFMT_POSIX_UINT32_LE: return atcacert_date_dec_posix_uint32_le(formatted_date, timestamp); case DATEFMT_RFC5280_GEN: return atcacert_date_dec_rfc5280_gen(formatted_date, timestamp); - default: return ATCACERT_E_BAD_PARAMS; + default: break; } - return ATCACERT_E_SUCCESS; + return ATCACERT_E_BAD_PARAMS; } int atcacert_date_get_max_date(atcacert_date_format_t format, atcacert_tm_utc_t* timestamp) { - if (timestamp == NULL || format < 0 || format >= sizeof(ATCACERT_DATE_FORMAT_SIZES) / sizeof(ATCACERT_DATE_FORMAT_SIZES[0])) + if (timestamp == NULL || format >= sizeof(ATCACERT_DATE_FORMAT_SIZES) / sizeof(ATCACERT_DATE_FORMAT_SIZES[0])) { return ATCACERT_E_BAD_PARAMS; } @@ -1066,7 +1066,7 @@ int atcacert_date_dec_compcert(const uint8_t enc_dates[3], * Minutes and seconds are always zero. */ - if (enc_dates == NULL || issue_date == NULL || expire_date == NULL || expire_date_format < 0 || expire_date_format >= sizeof(ATCACERT_DATE_FORMAT_SIZES) / sizeof(ATCACERT_DATE_FORMAT_SIZES[0])) + if (enc_dates == NULL || issue_date == NULL || expire_date == NULL || expire_date_format >= sizeof(ATCACERT_DATE_FORMAT_SIZES) / sizeof(ATCACERT_DATE_FORMAT_SIZES[0])) { return ATCACERT_E_BAD_PARAMS; } @@ -1099,4 +1099,4 @@ int atcacert_date_dec_compcert(const uint8_t enc_dates[3], } return ATCACERT_E_SUCCESS; -} \ No newline at end of file +} diff --git a/lib/atcacert/atcacert_date.h b/lib/atcacert/atcacert_date.h index 4ced5a0e4..28e8b5175 100644 --- a/lib/atcacert/atcacert_date.h +++ b/lib/atcacert/atcacert_date.h @@ -62,14 +62,13 @@ typedef struct atcacert_tm_utc_s /** * Date formats. */ -typedef enum atcacert_date_format_e -{ - DATEFMT_ISO8601_SEP, //!< ISO8601 full date YYYY-MM-DDThh:mm:ssZ - DATEFMT_RFC5280_UTC, //!< RFC 5280 (X.509) 4.1.2.5.1 UTCTime format YYMMDDhhmmssZ - DATEFMT_POSIX_UINT32_BE, //!< POSIX (aka UNIX) date format. Seconds since Jan 1, 1970. 32 bit unsigned integer, big endian. - DATEFMT_POSIX_UINT32_LE, //!< POSIX (aka UNIX) date format. Seconds since Jan 1, 1970. 32 bit unsigned integer, little endian. - DATEFMT_RFC5280_GEN //!< RFC 5280 (X.509) 4.1.2.5.2 GeneralizedTime format YYYYMMDDhhmmssZ -} atcacert_date_format_t; +#define DATEFMT_ISO8601_SEP 0 //!< ISO8601 full date YYYY-MM-DDThh:mm:ssZ +#define DATEFMT_RFC5280_UTC 1 //!< RFC 5280 (X.509) 4.1.2.5.1 UTCTime format YYMMDDhhmmssZ +#define DATEFMT_POSIX_UINT32_BE 2 //!< POSIX (aka UNIX) date format. Seconds since Jan 1, 1970. 32 bit unsigned integer, big endian. +#define DATEFMT_POSIX_UINT32_LE 3 //!< POSIX (aka UNIX) date format. Seconds since Jan 1, 1970. 32 bit unsigned integer, little endian. +#define DATEFMT_RFC5280_GEN 4 //!< RFC 5280 (X.509) 4.1.2.5.2 GeneralizedTime format YYYYMMDDhhmmssZ + +typedef uint8_t atcacert_date_format_t; #define DATEFMT_ISO8601_SEP_SIZE (20) #define DATEFMT_RFC5280_UTC_SIZE (13) @@ -191,4 +190,4 @@ int atcacert_date_dec_posix_uint32_le(const uint8_t formatted_date[DATEFMT_ } #endif -#endif \ No newline at end of file +#endif diff --git a/lib/atcacert/atcacert_pem.c b/lib/atcacert/atcacert_pem.c index d2f2bb4c1..c897b69ab 100644 --- a/lib/atcacert/atcacert_pem.c +++ b/lib/atcacert/atcacert_pem.c @@ -71,7 +71,7 @@ int atcacert_encode_pem(const uint8_t* der, { if (status == ATCA_SMALL_BUFFER) { - status = ATCACERT_E_BUFFER_TOO_SMALL; + status = (ATCA_STATUS)ATCACERT_E_BUFFER_TOO_SMALL; } return status; } @@ -112,6 +112,8 @@ int atcacert_decode_pem(const char* pem, const char* data_pos = NULL; const char* footer_pos = NULL; + (void)pem_size; + if (pem == NULL || der == NULL || der_size == NULL || header == NULL || footer == NULL) { return ATCACERT_E_BAD_PARAMS; @@ -142,7 +144,7 @@ int atcacert_decode_pem(const char* pem, { if (status == ATCA_SMALL_BUFFER) { - status = ATCACERT_E_BUFFER_TOO_SMALL; + status = (ATCA_STATUS)ATCACERT_E_BUFFER_TOO_SMALL; } return status; } @@ -192,4 +194,4 @@ int atcacert_decode_pem_csr(const char* pem_csr, size_t pem_csr_size, uint8_t* d der_csr_size, PEM_CSR_BEGIN, PEM_CSR_END); -} \ No newline at end of file +} diff --git a/lib/calib/calib_basic.c b/lib/calib/calib_basic.c index 8db368ab9..b9e08b571 100644 --- a/lib/calib/calib_basic.c +++ b/lib/calib/calib_basic.c @@ -37,6 +37,7 @@ ATCA_STATUS calib_wakeup_i2c(ATCADevice device) { ATCA_STATUS status = ATCA_BAD_PARAM; + uint8_t second_byte = 0x01; // I2C general call should not interpreted as an addr write ATCAIface iface = atGetIFace(device); if (iface) @@ -44,6 +45,7 @@ ATCA_STATUS calib_wakeup_i2c(ATCADevice device) uint8_t retries = atca_iface_get_retries(iface); uint8_t address = atcab_get_device_address(device); uint32_t temp; + uint32_t wake; uint16_t rxlen; do @@ -71,17 +73,17 @@ ATCA_STATUS calib_wakeup_i2c(ATCADevice device) else { - (void)atsend(iface, 0x00, NULL, 0); + (void)atsend(iface, 0x00, &second_byte, sizeof(second_byte)); } #else - (void)atsend(iface, 0x00, NULL, 0); + (void)atsend(iface, 0x00, &second_byte, sizeof(second_byte)); #endif atca_delay_us(atca_iface_get_wake_delay(iface)); - rxlen = sizeof(temp); + rxlen = sizeof(wake); if (ATCA_SUCCESS == status) { - status = atreceive(iface, address, (uint8_t*)&temp, &rxlen); + status = atreceive(iface, address, (uint8_t*)&wake, &rxlen); } if ((ATCA_SUCCESS == status) && (100000UL < iface->mIfaceCFG->atcai2c.baud)) @@ -92,7 +94,7 @@ ATCA_STATUS calib_wakeup_i2c(ATCADevice device) if (ATCA_SUCCESS == status) { - status = hal_check_wake((uint8_t*)&temp, rxlen); + status = hal_check_wake((uint8_t*)&wake, rxlen); } } while (0 < retries-- && ATCA_SUCCESS != status); @@ -126,75 +128,75 @@ ATCA_STATUS calib_wakeup(ATCADevice device) { status = ATCA_SUCCESS; } - } - #endif - return status; } + return status; +} + /** \brief idle the CryptoAuth device * \param[in] device Device context pointer * \return ATCA_SUCCESS on success, otherwise an error code. */ - ATCA_STATUS calib_idle(ATCADevice device) - { - ATCA_STATUS status = ATCA_BAD_PARAM; +ATCA_STATUS calib_idle(ATCADevice device) +{ + ATCA_STATUS status = ATCA_BAD_PARAM; #ifdef ATCA_HAL_LEGACY_API - status = atidle(device->mIface); + status = atidle(&device->mIface); #else - if (atca_iface_is_kit(&device->mIface) || (ATCA_SWI_IFACE == device->mIface.mIfaceCFG->iface_type)) + if (atca_iface_is_kit(&device->mIface) || (ATCA_SWI_IFACE == device->mIface.mIfaceCFG->iface_type)) + { + status = atidle(&device->mIface); + } + else + { + if (ECC204 != atcab_get_device_type_ext(device)) { - status = atidle(&device->mIface); + uint8_t command = 0x02; + status = atsend(&device->mIface, atcab_get_device_address(device), &command, 1); } else { - if (ECC204 != atcab_get_device_type_ext(device)) - { - uint8_t command = 0x02; - status = atsend(&device->mIface, atcab_get_device_address(device), &command, 1); - } - else - { - status = ATCA_SUCCESS; - } + status = ATCA_SUCCESS; } -#endif - return status; } +#endif + return status; +} /** \brief invoke sleep on the CryptoAuth device * \param[in] device Device context pointer * \return ATCA_SUCCESS on success, otherwise an error code. */ - ATCA_STATUS calib_sleep(ATCADevice device) - { - ATCA_STATUS status = ATCA_BAD_PARAM; +ATCA_STATUS calib_sleep(ATCADevice device) +{ + ATCA_STATUS status = ATCA_BAD_PARAM; #ifdef ATCA_HAL_LEGACY_API - status = atsleep(device->mIface); + status = atsleep(&device->mIface); #else - if (atca_iface_is_kit(&device->mIface) || (ATCA_SWI_IFACE == device->mIface.mIfaceCFG->iface_type)) - { - status = atsleep(&device->mIface); - } - else - { - uint8_t command = 0x01; - status = atsend(&device->mIface, atcab_get_device_address(device), &command, 1); - } -#endif - return status; + if (atca_iface_is_kit(&device->mIface) || (ATCA_SWI_IFACE == device->mIface.mIfaceCFG->iface_type)) + { + status = atsleep(&device->mIface); + } + else + { + uint8_t command = 0x01; + status = atsend(&device->mIface, atcab_get_device_address(device), &command, 1); } +#endif + return status; +} /** \brief common cleanup code which idles the device after any operation * \param[in] device Device context pointer * \return ATCA_SUCCESS on success, otherwise an error code. */ - ATCA_STATUS _calib_exit(ATCADevice device) - { - return calib_idle(device); - } +ATCA_STATUS _calib_exit(ATCADevice device) +{ + return calib_idle(device); +} /** \brief Compute the address given the zone, slot, block, and offset @@ -206,41 +208,41 @@ ATCA_STATUS calib_wakeup(ATCADevice device) * \param[out] addr Pointer to the address of data or configuration or OTP zone. * \return ATCA_SUCCESS on success, otherwise an error code. */ - ATCA_STATUS calib_get_addr(uint8_t zone, uint16_t slot, uint8_t block, uint8_t offset, uint16_t* addr) - { - ATCA_STATUS status = ATCA_SUCCESS; - uint8_t mem_zone = zone & 0x03; +ATCA_STATUS calib_get_addr(uint8_t zone, uint16_t slot, uint8_t block, uint8_t offset, uint16_t* addr) +{ + ATCA_STATUS status = ATCA_SUCCESS; + uint8_t mem_zone = zone & 0x03; - if (addr == NULL) - { - return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); - } - if ((mem_zone != ATCA_ZONE_CONFIG) && (mem_zone != ATCA_ZONE_DATA) && (mem_zone != ATCA_ZONE_OTP)) + if (addr == NULL) + { + return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); + } + if ((mem_zone != ATCA_ZONE_CONFIG) && (mem_zone != ATCA_ZONE_DATA) && (mem_zone != ATCA_ZONE_OTP)) + { + return ATCA_TRACE(ATCA_BAD_PARAM, "Invalid zone received"); + } + do + { + // Initialize the addr to 00 + *addr = 0; + // Mask the offset + offset = offset & (uint8_t)0x07; + if ((mem_zone == ATCA_ZONE_CONFIG) || (mem_zone == ATCA_ZONE_OTP)) { - return ATCA_TRACE(ATCA_BAD_PARAM, "Invalid zone received"); + *addr = block << 3; + *addr |= offset; } - do + else // ATCA_ZONE_DATA { - // Initialize the addr to 00 - *addr = 0; - // Mask the offset - offset = offset & (uint8_t)0x07; - if ((mem_zone == ATCA_ZONE_CONFIG) || (mem_zone == ATCA_ZONE_OTP)) - { - *addr = block << 3; - *addr |= offset; - } - else // ATCA_ZONE_DATA - { - *addr = slot << 3; - *addr |= offset; - *addr |= block << 8; - } + *addr = slot << 3; + *addr |= offset; + *addr |= block << 8; } - while (0); - - return status; } + while (0); + + return status; +} /** \brief Compute the address given the zone, slot, block, and offset for ECC204 device * \param[in] zone Zone to get address from. Config(1) or @@ -252,24 +254,25 @@ ATCA_STATUS calib_wakeup(ATCADevice device) * * \return ATCA_SUCCESS on success, otherwise an error code. */ - ATCA_STATUS calib_ecc204_get_addr(uint8_t zone, uint16_t slot, uint8_t block, uint8_t offset, uint16_t* addr) - { - ATCA_STATUS status = ATCA_SUCCESS; +ATCA_STATUS calib_ecc204_get_addr(uint8_t zone, uint16_t slot, uint8_t block, uint8_t offset, uint16_t* addr) +{ + ATCA_STATUS status = ATCA_SUCCESS; - (void)offset; + ((void)zone); + ((void)offset); - if (addr == NULL) - { - return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); - } + if (addr == NULL) + { + return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); + } - // Initialize the addr to 00 - *addr = 0; - *addr = slot << 3; - *addr |= block << 8; + // Initialize the addr to 00 + *addr = 0; + *addr = slot << 3; + *addr |= block << 8; - return status; - } + return status; +} /** \brief Gets the size of the specified zone in bytes. * @@ -281,90 +284,90 @@ ATCA_STATUS calib_wakeup(ATCADevice device) * * \return ATCA_SUCCESS on success, otherwise an error code. */ - ATCA_STATUS calib_get_zone_size(ATCADevice device, uint8_t zone, uint16_t slot, size_t* size) +ATCA_STATUS calib_get_zone_size(ATCADevice device, uint8_t zone, uint16_t slot, size_t* size) +{ + ATCA_STATUS status = ATCA_SUCCESS; + + if ((device == NULL) || (size == NULL)) { - ATCA_STATUS status = ATCA_SUCCESS; + return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); + } - if ((device == NULL) || (size == NULL)) + if (device->mIface.mIfaceCFG->devtype == ATSHA204A) + { + switch (zone) { - return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); + case ATCA_ZONE_CONFIG: *size = 88; break; + case ATCA_ZONE_OTP: *size = 64; break; + case ATCA_ZONE_DATA: *size = 32; break; + default: status = ATCA_TRACE(ATCA_BAD_PARAM, "Invalid zone received"); break; } - - if (device->mIface.mIfaceCFG->devtype == ATSHA204A) + } + else if (device->mIface.mIfaceCFG->devtype == ATSHA206A) + { + switch (zone) { - switch (zone) - { - case ATCA_ZONE_CONFIG: *size = 88; break; - case ATCA_ZONE_OTP: *size = 64; break; - case ATCA_ZONE_DATA: *size = 32; break; - default: status = ATCA_TRACE(ATCA_BAD_PARAM, "Invalid zone received"); break; - } + case ATCA_ZONE_CONFIG: *size = 88; break; + case ATCA_ZONE_OTP: *size = 0; break; + case ATCA_ZONE_DATA: *size = 32; break; + default: status = ATCA_TRACE(ATCA_BAD_PARAM, "Invalid zone received"); break; } - else if (device->mIface.mIfaceCFG->devtype == ATSHA206A) + } +#ifdef ATCA_ECC204_SUPPORT + else if (ECC204 == device->mIface.mIfaceCFG->devtype) + { + switch (zone) { - switch (zone) + case ATCA_ECC204_ZONE_CONFIG: *size = 16; break; + case ATCA_ECC204_ZONE_DATA: + if ((0 == slot) || (3 == slot)) { - case ATCA_ZONE_CONFIG: *size = 88; break; - case ATCA_ZONE_OTP: *size = 0; break; - case ATCA_ZONE_DATA: *size = 32; break; - default: status = ATCA_TRACE(ATCA_BAD_PARAM, "Invalid zone received"); break; + *size = 32; } - } -#ifdef ATCA_ECC204_SUPPORT - else if (ECC204 == device->mIface.mIfaceCFG->devtype) - { - switch (zone) + else if (1 == slot) { - case ATCA_ECC204_ZONE_CONFIG: *size = 16; break; - case ATCA_ECC204_ZONE_DATA: - if ((0 == slot) || (3 == slot)) - { - *size = 32; - } - else if (1 == slot) - { - *size = 320; - } - else if (2 == slot) - { - *size = 64; - } - else - { - status = ATCA_TRACE(ATCA_BAD_PARAM, "Invalid slot received"); - } - break; - default: status = ATCA_TRACE(ATCA_BAD_PARAM, "Invalid zone received"); break; + *size = 320; + } + else if (2 == slot) + { + *size = 64; + } + else + { + status = ATCA_TRACE(ATCA_BAD_PARAM, "Invalid slot received"); } + break; + default: status = ATCA_TRACE(ATCA_BAD_PARAM, "Invalid zone received"); break; } + } #endif - else + else + { + switch (zone) { - switch (zone) + case ATCA_ZONE_CONFIG: *size = 128; break; + case ATCA_ZONE_OTP: *size = 64; break; + case ATCA_ZONE_DATA: + if (slot < 8) { - case ATCA_ZONE_CONFIG: *size = 128; break; - case ATCA_ZONE_OTP: *size = 64; break; - case ATCA_ZONE_DATA: - if (slot < 8) - { - *size = 36; - } - else if (slot == 8) - { - *size = 416; - } - else if (slot < 16) - { - *size = 72; - } - else - { - status = ATCA_TRACE(ATCA_BAD_PARAM, "Invalid slot received"); - } - break; - default: status = ATCA_TRACE(ATCA_BAD_PARAM, "Invalid zone received"); break; + *size = 36; + } + else if (slot == 8) + { + *size = 416; + } + else if (slot < 16) + { + *size = 72; } + else + { + status = ATCA_TRACE(ATCA_BAD_PARAM, "Invalid slot received"); + } + break; + default: status = ATCA_TRACE(ATCA_BAD_PARAM, "Invalid zone received"); break; } - - return status; } + + return status; +} diff --git a/lib/calib/calib_basic.h b/lib/calib/calib_basic.h index af8e580eb..dbd972f5d 100644 --- a/lib/calib/calib_basic.h +++ b/lib/calib/calib_basic.h @@ -23,6 +23,14 @@ ATCA_STATUS calib_get_addr(uint8_t zone, uint16_t slot, uint8_t block, uint8_t o ATCA_STATUS calib_get_zone_size(ATCADevice device, uint8_t zone, uint16_t slot, size_t* size); ATCA_STATUS calib_ecc204_get_addr(uint8_t zone, uint16_t slot, uint8_t block, uint8_t offset, uint16_t* addr); +/* Helper Functions */ +ATCA_STATUS calib_is_locked(ATCADevice device, uint8_t zone, bool* is_locked); +ATCA_STATUS calib_is_slot_locked(ATCADevice device, uint16_t slot, bool* is_locked); +ATCA_STATUS calib_is_private(ATCADevice device, uint16_t slot, bool* is_private); +ATCA_STATUS calib_ecc204_is_locked(ATCADevice device, uint8_t zone, bool* is_locked); +ATCA_STATUS calib_ecc204_is_data_locked(ATCADevice device, bool* is_locked); +ATCA_STATUS calib_ecc204_is_config_locked(ATCADevice device, bool* is_locked); + //AES command functions ATCA_STATUS calib_aes(ATCADevice device, uint8_t mode, uint16_t key_id, const uint8_t* aes_in, uint8_t* aes_out); ATCA_STATUS calib_aes_encrypt(ATCADevice device, uint16_t key_id, uint8_t key_block, const uint8_t* plaintext, uint8_t* ciphertext); @@ -73,9 +81,6 @@ ATCA_STATUS calib_info_set_latch(ATCADevice device, bool state); ATCA_STATUS calib_info_get_latch(ATCADevice device, bool* state); ATCA_STATUS calib_info_privkey_valid(ATCADevice device, uint16_t key_id, uint8_t* is_valid); ATCA_STATUS calib_info_lock_status(ATCADevice device, uint16_t param2, uint8_t* is_locked); -ATCA_STATUS calib_ecc204_is_locked(ATCADevice device, uint8_t zone, bool* is_locked); -ATCA_STATUS calib_ecc204_is_data_locked(ATCADevice device, bool* is_locked); -ATCA_STATUS calib_ecc204_is_config_locked(ATCADevice device, bool* is_locked); // KDF command functions ATCA_STATUS calib_kdf(ATCADevice device, uint8_t mode, uint16_t key_id, const uint32_t details, const uint8_t* message, uint8_t* out_data, uint8_t* out_nonce); @@ -117,8 +122,6 @@ ATCA_STATUS calib_random(ATCADevice device, uint8_t* rand_out); // Read command functions ATCA_STATUS calib_read_zone(ATCADevice device, uint8_t zone, uint16_t slot, uint8_t block, uint8_t offset, uint8_t *data, uint8_t len); -ATCA_STATUS calib_is_locked(ATCADevice device, uint8_t zone, bool *is_locked); -ATCA_STATUS calib_is_slot_locked(ATCADevice device, uint16_t slot, bool *is_locked); ATCA_STATUS calib_read_bytes_zone(ATCADevice device, uint8_t zone, uint16_t slot, size_t offset, uint8_t *data, size_t length); ATCA_STATUS calib_read_serial_number(ATCADevice device, uint8_t* serial_number); ATCA_STATUS calib_read_pubkey(ATCADevice device, uint16_t slot, uint8_t *public_key); @@ -203,7 +206,7 @@ ATCA_STATUS calib_ecc204_write(ATCADevice device, uint8_t zone, uint16_t address const uint8_t *mac); ATCA_STATUS calib_ecc204_write_zone(ATCADevice device, uint8_t zone, uint16_t slot, uint8_t block, uint8_t offset, const uint8_t *data, uint8_t len); -ATCA_STATUS calib_ecc204_write_config_zone(ATCADevice device, uint8_t* config_data); +ATCA_STATUS calib_ecc204_write_config_zone(ATCADevice device, const uint8_t* config_data); ATCA_STATUS calib_ecc204_write_bytes_zone(ATCADevice device, uint8_t zone, uint16_t slot, size_t block, const uint8_t *data, size_t length); diff --git a/lib/calib/calib_command.c b/lib/calib/calib_command.c index 8d2171c67..c73b0bb5b 100644 --- a/lib/calib/calib_command.c +++ b/lib/calib/calib_command.c @@ -41,6 +41,8 @@ */ ATCA_STATUS atCheckMAC(ATCADeviceType device_type, ATCAPacket *packet) { + ((void)device_type); + // Set the opcode & parameters packet->opcode = ATCA_CHECKMAC; packet->txsize = CHECKMAC_COUNT; @@ -55,6 +57,8 @@ ATCA_STATUS atCheckMAC(ATCADeviceType device_type, ATCAPacket *packet) */ ATCA_STATUS atCounter(ATCADeviceType device_type, ATCAPacket *packet) { + ((void)device_type); + // Set the opcode & parameters packet->opcode = ATCA_COUNTER; packet->txsize = COUNTER_COUNT; @@ -70,6 +74,8 @@ ATCA_STATUS atCounter(ATCADeviceType device_type, ATCAPacket *packet) */ ATCA_STATUS atDeriveKey(ATCADeviceType device_type, ATCAPacket *packet, bool has_mac) { + ((void)device_type); + // Set the opcode & parameters packet->opcode = ATCA_DERIVE_KEY; @@ -94,6 +100,8 @@ ATCA_STATUS atDeriveKey(ATCADeviceType device_type, ATCAPacket *packet, bool has */ ATCA_STATUS atECDH(ATCADeviceType device_type, ATCAPacket *packet) { + ((void)device_type); + // Set the opcode & parameters packet->opcode = ATCA_ECDH; packet->txsize = ECDH_COUNT; @@ -109,6 +117,8 @@ ATCA_STATUS atECDH(ATCADeviceType device_type, ATCAPacket *packet) */ ATCA_STATUS atGenDig(ATCADeviceType device_type, ATCAPacket *packet, bool is_no_mac_key) { + ((void)device_type); + // Set the opcode & parameters packet->opcode = ATCA_GENDIG; @@ -135,6 +145,8 @@ ATCA_STATUS atGenDig(ATCADeviceType device_type, ATCAPacket *packet, bool is_no_ */ ATCA_STATUS atGenKey(ATCADeviceType device_type, ATCAPacket *packet) { + ((void)device_type); + // Set the opcode & parameters packet->opcode = ATCA_GENKEY; @@ -157,6 +169,8 @@ ATCA_STATUS atGenKey(ATCADeviceType device_type, ATCAPacket *packet) */ ATCA_STATUS atHMAC(ATCADeviceType device_type, ATCAPacket *packet) { + ((void)device_type); + // Set the opcode & parameters packet->opcode = ATCA_HMAC; packet->txsize = HMAC_COUNT; @@ -171,6 +185,8 @@ ATCA_STATUS atHMAC(ATCADeviceType device_type, ATCAPacket *packet) */ ATCA_STATUS atInfo(ATCADeviceType device_type, ATCAPacket *packet) { + ((void)device_type); + // Set the opcode & parameters packet->opcode = ATCA_INFO; packet->txsize = INFO_COUNT; @@ -185,6 +201,8 @@ ATCA_STATUS atInfo(ATCADeviceType device_type, ATCAPacket *packet) */ ATCA_STATUS atLock(ATCADeviceType device_type, ATCAPacket *packet) { + ((void)device_type); + // Set the opcode & parameters packet->opcode = ATCA_LOCK; packet->txsize = LOCK_COUNT; @@ -199,6 +217,8 @@ ATCA_STATUS atLock(ATCADeviceType device_type, ATCAPacket *packet) */ ATCA_STATUS atMAC(ATCADeviceType device_type, ATCAPacket *packet) { + ((void)device_type); + // Set the opcode & parameters // variable packet size packet->opcode = ATCA_MAC; @@ -221,6 +241,8 @@ ATCA_STATUS atMAC(ATCADeviceType device_type, ATCAPacket *packet) */ ATCA_STATUS atNonce(ATCADeviceType device_type, ATCAPacket *packet) { + ((void)device_type); + // Set the opcode & parameters // variable packet size uint8_t calc_mode = packet->param1 & NONCE_MODE_MASK; @@ -261,6 +283,8 @@ ATCA_STATUS atNonce(ATCADeviceType device_type, ATCAPacket *packet) */ ATCA_STATUS atPause(ATCADeviceType device_type, ATCAPacket *packet) { + ((void)device_type); + // Set the opcode & parameters packet->opcode = ATCA_PAUSE; packet->txsize = PAUSE_COUNT; @@ -275,6 +299,8 @@ ATCA_STATUS atPause(ATCADeviceType device_type, ATCAPacket *packet) */ ATCA_STATUS atPrivWrite(ATCADeviceType device_type, ATCAPacket *packet) { + ((void)device_type); + // Set the opcode & parameters packet->opcode = ATCA_PRIVWRITE; packet->txsize = PRIVWRITE_COUNT; @@ -289,6 +315,8 @@ ATCA_STATUS atPrivWrite(ATCADeviceType device_type, ATCAPacket *packet) */ ATCA_STATUS atRandom(ATCADeviceType device_type, ATCAPacket *packet) { + ((void)device_type); + // Set the opcode & parameters packet->opcode = ATCA_RANDOM; packet->txsize = RANDOM_COUNT; @@ -303,6 +331,8 @@ ATCA_STATUS atRandom(ATCADeviceType device_type, ATCAPacket *packet) */ ATCA_STATUS atRead(ATCADeviceType device_type, ATCAPacket *packet) { + ((void)device_type); + // Set the opcode & parameters packet->opcode = ATCA_READ; packet->txsize = READ_COUNT; @@ -317,6 +347,8 @@ ATCA_STATUS atRead(ATCADeviceType device_type, ATCAPacket *packet) */ ATCA_STATUS atSecureBoot(ATCADeviceType device_type, ATCAPacket *packet) { + ((void)device_type); + packet->opcode = ATCA_SECUREBOOT; packet->txsize = ATCA_CMD_SIZE_MIN; @@ -348,6 +380,8 @@ ATCA_STATUS atSecureBoot(ATCADeviceType device_type, ATCAPacket *packet) */ ATCA_STATUS atSHA(ATCADeviceType device_type, ATCAPacket *packet, uint16_t write_context_size) { + ((void)device_type); + // Set the opcode & parameters packet->opcode = ATCA_SHA; @@ -408,6 +442,8 @@ ATCA_STATUS atSign(ATCADeviceType device_type, ATCAPacket *packet) */ ATCA_STATUS atUpdateExtra(ATCADeviceType device_type, ATCAPacket *packet) { + ((void)device_type); + // Set the opcode & parameters packet->opcode = ATCA_UPDATE_EXTRA; packet->txsize = UPDATE_COUNT; @@ -422,6 +458,8 @@ ATCA_STATUS atUpdateExtra(ATCADeviceType device_type, ATCAPacket *packet) */ ATCA_STATUS atVerify(ATCADeviceType device_type, ATCAPacket *packet) { + ((void)device_type); + // Set the opcode & parameters packet->opcode = ATCA_VERIFY; @@ -507,6 +545,8 @@ ATCA_STATUS atWrite(ATCADeviceType device_type, ATCAPacket *packet, bool has_mac */ ATCA_STATUS atAES(ATCADeviceType device_type, ATCAPacket *packet) { + ((void)device_type); + // Set the opcode & parameters packet->opcode = ATCA_AES; packet->txsize = ATCA_CMD_SIZE_MIN; @@ -530,6 +570,8 @@ ATCA_STATUS atAES(ATCADeviceType device_type, ATCAPacket *packet) */ ATCA_STATUS atSelfTest(ATCADeviceType device_type, ATCAPacket *packet) { + ((void)device_type); + // Set the opcode & parameters packet->opcode = ATCA_SELFTEST; packet->txsize = ATCA_CMD_SIZE_MIN; @@ -537,8 +579,6 @@ ATCA_STATUS atSelfTest(ATCADeviceType device_type, ATCAPacket *packet) return ATCA_SUCCESS; } - - /** \brief ATCACommand KDF method * \param[in] ca_cmd Instance * \param[in] packet Pointer to the packet containing the command being @@ -547,6 +587,8 @@ ATCA_STATUS atSelfTest(ATCADeviceType device_type, ATCAPacket *packet) */ ATCA_STATUS atKDF(ATCADeviceType device_type, ATCAPacket *packet) { + ((void)device_type); + // Set the opcode & parameters packet->opcode = ATCA_KDF; diff --git a/lib/calib/calib_ecdh.c b/lib/calib/calib_ecdh.c index b0f67d1a8..bb1f12612 100644 --- a/lib/calib/calib_ecdh.c +++ b/lib/calib/calib_ecdh.c @@ -161,7 +161,7 @@ ATCA_STATUS calib_ecdh_enc(ATCADevice device, uint16_t key_id, const uint8_t* pu #if defined(ATCA_USE_CONSTANT_HOST_NONCE) if ((status = calib_read_enc(device, key_id | 0x0001, 0, pms, read_key, read_key_id)) != ATCA_SUCCESS) #else - if ((status = atcab_read_enc(key_id | 0x0001, 0, pms, read_key, read_key_id, num_in)) != ATCA_SUCCESS) + if ((status = calib_read_enc(device, key_id | 0x0001, 0, pms, read_key, read_key_id, num_in)) != ATCA_SUCCESS) #endif { ATCA_TRACE(status, "Encrypted read failed"); break; diff --git a/lib/calib/calib_execution.c b/lib/calib/calib_execution.c index b83e55252..376eebf09 100644 --- a/lib/calib/calib_execution.c +++ b/lib/calib/calib_execution.c @@ -215,14 +215,14 @@ static const device_execution_time_t device_execution_time_ecc204[] = { * \param[in] ca_cmd Command object for which the execution times are associated * \return ATCA_SUCCESS */ -ATCA_STATUS calib_get_execution_time(uint8_t opcode, ATCACommand ca_cmd) +ATCA_STATUS calib_get_execution_time(uint8_t opcode, ATCADevice device) { ATCA_STATUS status = ATCA_SUCCESS; const device_execution_time_t *execution_times; uint8_t i, no_of_commands; - switch (ca_cmd->dt) + switch (device->mIface.mIfaceCFG->devtype) { case ATSHA204A: execution_times = device_execution_time_204; @@ -245,12 +245,12 @@ ATCA_STATUS calib_get_execution_time(uint8_t opcode, ATCACommand ca_cmd) break; case ATECC608: - if (ca_cmd->clock_divider == ATCA_CHIPMODE_CLOCK_DIV_M1) + if (device->clock_divider == ATCA_CHIPMODE_CLOCK_DIV_M1) { execution_times = device_execution_time_608_m1; no_of_commands = sizeof(device_execution_time_608_m1) / sizeof(device_execution_time_t); } - else if (ca_cmd->clock_divider == ATCA_CHIPMODE_CLOCK_DIV_M2) + else if (device->clock_divider == ATCA_CHIPMODE_CLOCK_DIV_M2) { execution_times = device_execution_time_608_m2; no_of_commands = sizeof(device_execution_time_608_m2) / sizeof(device_execution_time_t); @@ -274,18 +274,18 @@ ATCA_STATUS calib_get_execution_time(uint8_t opcode, ATCACommand ca_cmd) break; } - ca_cmd->execution_time_msec = ATCA_UNSUPPORTED_CMD; + device->execution_time_msec = ATCA_UNSUPPORTED_CMD; for (i = 0; i < no_of_commands; i++) { if (execution_times[i].opcode == opcode) { - ca_cmd->execution_time_msec = execution_times[i].execution_time_msec; + device->execution_time_msec = execution_times[i].execution_time_msec; break; } } - if (ca_cmd->execution_time_msec == ATCA_UNSUPPORTED_CMD) + if (device->execution_time_msec == ATCA_UNSUPPORTED_CMD) { status = ATCA_BAD_OPCODE; } @@ -304,7 +304,8 @@ ATCA_STATUS calib_execute_send(ATCADevice device, uint8_t device_address, uint8_ } #ifdef ATCA_HAL_LEGACY_API - status = atsend(device->mIface, 0xFF, (uint8_t*)txdata, txlength - 1); + ((void)device_address); + status = atsend(&device->mIface, 0xFF, (uint8_t*)txdata, txlength - 1); #else if (atca_iface_is_kit(&device->mIface)) { @@ -329,8 +330,6 @@ ATCA_STATUS calib_execute_send(ATCADevice device, uint8_t device_address, uint8_ ATCA_STATUS calib_execute_receive(ATCADevice device, uint8_t device_address, uint8_t* rxdata, uint16_t* rxlength) { ATCA_STATUS status = ATCA_COMM_FAIL; - uint16_t read_length = 1; - uint8_t word_address; if ((NULL == rxlength) || (NULL == rxdata)) { @@ -338,8 +337,12 @@ ATCA_STATUS calib_execute_receive(ATCADevice device, uint8_t device_address, uin } #ifdef ATCA_HAL_LEGACY_API - status = atsend(device->mIface, txdata[0], (uint8_t*)txdata, txlength); + ((void)device_address); + status = atreceive(&device->mIface, 0, rxdata, rxlength); #else + uint16_t read_length = 1; + uint8_t word_address; + if (atca_iface_is_kit(&device->mIface)) { status = atreceive(&device->mIface, 0, rxdata, rxlength); @@ -437,11 +440,11 @@ ATCA_STATUS calib_execute_command(ATCAPacket* packet, ATCADevice device) do { #ifdef ATCA_NO_POLL - if ((status = calib_get_execution_time(packet->opcode, device->mCommands)) != ATCA_SUCCESS) + if ((status = calib_get_execution_time(packet->opcode, device)) != ATCA_SUCCESS) { return status; } - execution_or_wait_time = device->mCommands->execution_time_msec; + execution_or_wait_time = device->execution_time_msec; max_delay_count = 0; #else execution_or_wait_time = ATCA_POLLING_INIT_TIME_MSEC; diff --git a/lib/calib/calib_execution.h b/lib/calib/calib_execution.h index 11c69acad..963156424 100644 --- a/lib/calib/calib_execution.h +++ b/lib/calib/calib_execution.h @@ -63,7 +63,7 @@ typedef struct uint16_t execution_time_msec; }device_execution_time_t; -ATCA_STATUS calib_get_execution_time(uint8_t opcode, ATCACommand ca_cmd); +ATCA_STATUS calib_get_execution_time(uint8_t opcode, ATCADevice device); #endif #ifndef ATCA_HAL_LEGACY_API diff --git a/lib/calib/calib_helpers.c b/lib/calib/calib_helpers.c new file mode 100644 index 000000000..ef38f7ce7 --- /dev/null +++ b/lib/calib/calib_helpers.c @@ -0,0 +1,264 @@ +/** + * \file + * \brief CryptoAuthLib Basic API - Helper Functions to + * + * \copyright (c) 2015-2020 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include "cryptoauthlib.h" + +/** \brief Executes Read command, which reads the configuration zone to see if + * the specified slot is locked. + * + * \param[in] device Device context pointer + * \param[in] slot Slot to query for locked (slot 0-15) + * \param[out] is_locked Lock state returned here. True if locked. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS calib_is_slot_locked(ATCADevice device, uint16_t slot, bool* is_locked) +{ + ATCA_STATUS status = ATCA_GEN_FAIL; + uint8_t data[ATCA_WORD_SIZE]; + uint16_t slot_locked; + + do + { + if ((slot > 15) || (is_locked == NULL)) + { + status = ATCA_TRACE(ATCA_BAD_PARAM, "Either Invalid slot or NULL pointer received"); + break; + } + + // Read the word with the lock bytes ( SlotLock[2], RFU[2] ) (config block = 2, word offset = 6) + if ((status = calib_read_zone(device, ATCA_ZONE_CONFIG, 0, 2 /*block*/, 6 /*offset*/, data, ATCA_WORD_SIZE)) != ATCA_SUCCESS) + { + ATCA_TRACE(status, "calib_read_zone - failed"); + break; + } + + slot_locked = ((uint16_t)data[0]) | ((uint16_t)data[1] << 8); + *is_locked = ((slot_locked & (1 << slot)) == 0); + } + while (0); + + return status; +} + +/** \brief Executes Read command, which reads the configuration zone to see if + * the specified zone is locked. + * + * \param[in] device Device context pointer + * \param[in] zone The zone to query for locked (use LOCK_ZONE_CONFIG or + * LOCK_ZONE_DATA). + * \param[out] is_locked Lock state returned here. True if locked. + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS calib_is_locked(ATCADevice device, uint8_t zone, bool* is_locked) +{ + ATCA_STATUS status = ATCA_GEN_FAIL; + uint8_t data[ATCA_WORD_SIZE]; + + do + { + if (is_locked == NULL) + { + status = ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); + break; + } + + // Read the word with the lock bytes (UserExtra, Selector, LockValue, LockConfig) (config block = 2, word offset = 5) + if ((status = calib_read_zone(device, ATCA_ZONE_CONFIG, 0, 2 /*block*/, 5 /*offset*/, data, ATCA_WORD_SIZE)) != ATCA_SUCCESS) + { + ATCA_TRACE(status, "calib_read_zone - failed"); + break; + } + + // Determine the index into the word_data based on the zone we are querying for + switch (zone) + { + case LOCK_ZONE_CONFIG: *is_locked = (data[3] != 0x55); break; + case LOCK_ZONE_DATA: *is_locked = (data[2] != 0x55); break; + default: status = ATCA_TRACE(ATCA_BAD_PARAM, "Invalid zone received"); break; + } + } + while (0); + + return status; +} + + +#ifdef ATCA_ECC204_SUPPORT +/** \brief Use Info command to check ECC204 Config zone lock status + * + * \param[in] device Device context pointer + * \param[out] is_locked return lock status + * + * \return ATCA_SUCCESS on success, otherwise an error code + */ +ATCA_STATUS calib_ecc204_is_config_locked(ATCADevice device, bool* is_locked) +{ + ATCA_STATUS status = ATCA_SUCCESS; + uint16_t param2; + uint8_t slot = 0; + + if (NULL == is_locked) + { + return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer encountered"); + } + + while (slot <= 3) + { + param2 = ATCA_ECC204_ZONE_CONFIG | (slot << 1); + if (ATCA_SUCCESS != (status = calib_info_lock_status(device, param2, (uint8_t*)is_locked))) + { + *is_locked = false; + break; + } + + if (*is_locked) + { + slot += 1; // increment slot + } + else + { + break; + } + } + + return status; +} + +/** \brief Use Info command to check ECC204 Data zone lock status + * + * \param[in] device Device context pointer + * \param[out] is_locked return lock status + * + * \return ATCA_SUCCESS on success, otherwise an error code + */ +ATCA_STATUS calib_ecc204_is_data_locked(ATCADevice device, bool* is_locked) +{ + ATCA_STATUS status = ATCA_SUCCESS; + uint16_t param2; + uint8_t slot = 0; + + if (NULL == is_locked) + { + return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer encountered"); + } + + while (slot <= 3) + { + param2 = ATCA_ECC204_ZONE_DATA | (slot << 1); + if (ATCA_SUCCESS != (status = calib_info_lock_status(device, param2, (uint8_t*)is_locked))) + { + *is_locked = false; + break; + } + + if (*is_locked) + { + slot += 1; // increment slot + } + else + { + break; + } + } + + return status; +} + +/** \brief Use Info command to check config/data is locked or not + * + * \param[in] device Device contect pointer + * \param[in] zone Config/Data zone + * \param[out] is_locked return lock status here + * + * \return ATCA_SUCCESS on success, otherwise an error code + */ +ATCA_STATUS calib_ecc204_is_locked(ATCADevice device, uint8_t zone, bool* is_locked) +{ + ATCA_STATUS status = ATCA_SUCCESS; + + if (ATCA_ECC204_ZONE_CONFIG == zone) + { + status = calib_ecc204_is_config_locked(device, is_locked); + } + else if (ATCA_ECC204_ZONE_DATA == zone) + { + status = calib_ecc204_is_data_locked(device, is_locked); + } + else + { + status = ATCA_TRACE(ATCA_BAD_PARAM, "Invalid zone received"); + } + + return status; +} + +#endif + + +/** \brief Check if a slot is a private key + * + * \param[in] device Device context pointer + * \param[in] slot Slot to query (slot 0-15) + * \param[out] is_private return true if private + * + * \return ATCA_SUCCESS on success, otherwise an error code + */ +ATCA_STATUS calib_is_private(ATCADevice device, uint16_t slot, bool* is_private) +{ + ATCA_STATUS status = ATCA_BAD_PARAM; + ATCADeviceType dev_type = atcab_get_device_type_ext(device); + + if (device && is_private) + { + switch (dev_type) + { + case ATECC108A: + /* fallthrough */ + case ATECC508A: + /* fallthrough */ + case ATECC608: + { + uint8_t key_config[2] = { 0 }; + if (ATCA_SUCCESS == (status = calib_read_bytes_zone(device, ATCA_ZONE_CONFIG, 0, ATCA_KEY_CONFIG_OFFSET((size_t)slot), key_config, sizeof(key_config)))) + { + *is_private = (key_config[0] & ATCA_KEY_CONFIG_PRIVATE_MASK); + } + break; + } +#ifdef ATCA_ECC204_SUPPORT + case ECC204: + break; +#endif + default: + *is_private = false; + break; + } + } + + return status; +} diff --git a/lib/calib/calib_info.c b/lib/calib/calib_info.c index d289b5507..98c229091 100644 --- a/lib/calib/calib_info.c +++ b/lib/calib/calib_info.c @@ -176,7 +176,7 @@ ATCA_STATUS calib_info_privkey_valid(ATCADevice device, uint16_t key_id, uint8_t return calib_info_base(device, INFO_MODE_KEY_VALID, key_id, is_valid); } -#if defined(ATCA_ECC204_SUPPORT) +#ifdef ATCA_ECC204_SUPPORT /** \brief Use Info command to ECC204 config/data zone lock status * * \param[in] device Device context pointer @@ -189,113 +189,4 @@ ATCA_STATUS calib_info_lock_status(ATCADevice device, uint16_t param2, uint8_t* { return calib_info_base(device, INFO_MODE_LOCK_STATUS, param2, is_locked); } - -/** \brief Use Info command to check ECC204 Config zone lock status - * - * \param[in] device Device context pointer - * \param[out] is_locked return lock status - * - * \return ATCA_SUCCESS on success, otherwise an error code - */ -ATCA_STATUS calib_ecc204_is_config_locked(ATCADevice device, bool* is_locked) -{ - ATCA_STATUS status = ATCA_SUCCESS; - uint16_t param2; - uint8_t slot = 0; - - if (NULL == is_locked) - { - return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer encountered"); - } - - while (slot <= 3) - { - param2 = ATCA_ECC204_ZONE_CONFIG | (slot << 1); - if (ATCA_SUCCESS != (status = calib_info_lock_status(device, param2, (uint8_t*)is_locked))) - { - *is_locked = false; - break; - } - - if (*is_locked) - { - slot += 1; // increment slot - } - else - { - break; - } - } - - return status; -} - -/** \brief Use Info command to check ECC204 Data zone lock status - * - * \param[in] device Device context pointer - * \param[out] is_locked return lock status - * - * \return ATCA_SUCCESS on success, otherwise an error code - */ -ATCA_STATUS calib_ecc204_is_data_locked(ATCADevice device, bool* is_locked) -{ - ATCA_STATUS status = ATCA_SUCCESS; - uint16_t param2; - uint8_t slot = 0; - - if (NULL == is_locked) - { - return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer encountered"); - } - - while (slot <= 3) - { - param2 = ATCA_ECC204_ZONE_DATA | (slot << 1); - if (ATCA_SUCCESS != (status = calib_info_lock_status(device, param2, (uint8_t*)is_locked))) - { - *is_locked = false; - break; - } - - if (*is_locked) - { - slot += 1; // increment slot - } - else - { - break; - } - } - - return status; -} - -/** \brief Use Info command to check config/data is locked or not - * - * \param[in] device Device contect pointer - * \param[in] zone Config/Data zone - * \param[out] is_locked return lock status here - * - * \return ATCA_SUCCESS on success, otherwise an error code - */ -ATCA_STATUS calib_ecc204_is_locked(ATCADevice device, uint8_t zone, bool* is_locked) -{ - ATCA_STATUS status = ATCA_SUCCESS; - - if (ATCA_ECC204_ZONE_CONFIG == zone) - { - status = calib_ecc204_is_config_locked(device, is_locked); - } - else if (ATCA_ECC204_ZONE_DATA == zone) - { - status = calib_ecc204_is_data_locked(device, is_locked); - } - else - { - status = ATCA_TRACE(ATCA_BAD_PARAM, "Invalid zone received"); - } - - return status; -} - -#endif \ No newline at end of file +#endif diff --git a/lib/calib/calib_privwrite.c b/lib/calib/calib_privwrite.c index 448acbd7d..28cdd1c34 100644 --- a/lib/calib/calib_privwrite.c +++ b/lib/calib/calib_privwrite.c @@ -90,18 +90,18 @@ ATCA_STATUS calib_priv_write(ATCADevice device, uint16_t key_id, const uint8_t p else { // Read the device SN - if ((status = atcab_read_zone(ATCA_ZONE_CONFIG, 0, 0, 0, serial_num, 32)) != ATCA_SUCCESS) + if ((status = calib_read_zone(device, ATCA_ZONE_CONFIG, 0, 0, 0, serial_num, 32)) != ATCA_SUCCESS) { - ATCA_TRACE(status, "atcab_read_zone - failed"); + ATCA_TRACE(status, "calib_read_zone - failed"); break; } // Make the SN continuous by moving SN[4:8] right after SN[0:3] memmove(&serial_num[4], &serial_num[8], 5); // Send the random Nonce command - if ((status = atcab_nonce_rand(num_in, rand_out)) != ATCA_SUCCESS) + if ((status = calib_nonce_rand(device, num_in, rand_out)) != ATCA_SUCCESS) { - ATCA_TRACE(status, "atcab_nonce_rand - failed"); + ATCA_TRACE(status, "calib_nonce_rand - failed"); break; } @@ -126,9 +126,9 @@ ATCA_STATUS calib_priv_write(ATCADevice device, uint16_t key_id, const uint8_t p other_data[3] = (uint8_t)(write_key_id >> 8); // Send the GenDig command - if ((status = atcab_gendig(GENDIG_ZONE_DATA, write_key_id, other_data, sizeof(other_data))) != ATCA_SUCCESS) + if ((status = calib_gendig(device, GENDIG_ZONE_DATA, write_key_id, other_data, sizeof(other_data))) != ATCA_SUCCESS) { - ATCA_TRACE(status, "atcab_gendig - failed"); + ATCA_TRACE(status, "calib_gendig - failed"); break; } diff --git a/lib/calib/calib_read.c b/lib/calib/calib_read.c index b1196b210..b8a362e60 100644 --- a/lib/calib/calib_read.c +++ b/lib/calib/calib_read.c @@ -142,85 +142,7 @@ ATCA_STATUS calib_read_serial_number(ATCADevice device, uint8_t* serial_number) return status; } -/** \brief Executes Read command, which reads the configuration zone to see if - * the specified slot is locked. - * - * \param[in] device Device context pointer - * \param[in] slot Slot to query for locked (slot 0-15) - * \param[out] is_locked Lock state returned here. True if locked. - * - * \return ATCA_SUCCESS on success, otherwise an error code. - */ -ATCA_STATUS calib_is_slot_locked(ATCADevice device, uint16_t slot, bool *is_locked) -{ - ATCA_STATUS status = ATCA_GEN_FAIL; - uint8_t data[ATCA_WORD_SIZE]; - uint16_t slot_locked; - do - { - if ((slot > 15) || (is_locked == NULL)) - { - status = ATCA_TRACE(ATCA_BAD_PARAM, "Either Invalid slot or NULL pointer received"); - break; - } - - // Read the word with the lock bytes ( SlotLock[2], RFU[2] ) (config block = 2, word offset = 6) - if ((status = calib_read_zone(device, ATCA_ZONE_CONFIG, 0, 2 /*block*/, 6 /*offset*/, data, ATCA_WORD_SIZE)) != ATCA_SUCCESS) - { - ATCA_TRACE(status, "calib_read_zone - failed"); - break; - } - - slot_locked = ((uint16_t)data[0]) | ((uint16_t)data[1] << 8); - *is_locked = ((slot_locked & (1 << slot)) == 0); - } - while (0); - - return status; -} - -/** \brief Executes Read command, which reads the configuration zone to see if - * the specified zone is locked. - * - * \param[in] device Device context pointer - * \param[in] zone The zone to query for locked (use LOCK_ZONE_CONFIG or - * LOCK_ZONE_DATA). - * \param[out] is_locked Lock state returned here. True if locked. - * \return ATCA_SUCCESS on success, otherwise an error code. - */ -ATCA_STATUS calib_is_locked(ATCADevice device, uint8_t zone, bool *is_locked) -{ - ATCA_STATUS status = ATCA_GEN_FAIL; - uint8_t data[ATCA_WORD_SIZE]; - - do - { - if (is_locked == NULL) - { - status = ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); - break; - } - - // Read the word with the lock bytes (UserExtra, Selector, LockValue, LockConfig) (config block = 2, word offset = 5) - if ((status = calib_read_zone(device, ATCA_ZONE_CONFIG, 0, 2 /*block*/, 5 /*offset*/, data, ATCA_WORD_SIZE)) != ATCA_SUCCESS) - { - ATCA_TRACE(status, "calib_read_zone - failed"); - break; - } - - // Determine the index into the word_data based on the zone we are querying for - switch (zone) - { - case LOCK_ZONE_CONFIG: *is_locked = (data[3] != 0x55); break; - case LOCK_ZONE_DATA: *is_locked = (data[2] != 0x55); break; - default: status = ATCA_TRACE(ATCA_BAD_PARAM, "Invalid zone received"); break; - } - } - while (0); - - return status; -} /** \brief Executes Read command on a slot configured for encrypted reads and * decrypts the data to return it as plaintext. @@ -965,4 +887,4 @@ ATCA_STATUS calib_ecc204_cmp_config_zone(ATCADevice device, uint8_t* config_data return status; } -#endif \ No newline at end of file +#endif diff --git a/lib/calib/calib_sign.c b/lib/calib/calib_sign.c index e2075d601..253419358 100644 --- a/lib/calib/calib_sign.c +++ b/lib/calib/calib_sign.c @@ -211,6 +211,9 @@ ATCA_STATUS calib_ecc204_sign(ATCADevice device, uint16_t key_id, const uint8_t* ATCA_STATUS status = ATCA_SUCCESS; ATCAPacket packet; + packet.param1 = 0x00; + packet.param2 = key_id; + if ((NULL == device) || (NULL == msg)) { status = ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer encountered"); @@ -218,9 +221,6 @@ ATCA_STATUS calib_ecc204_sign(ATCADevice device, uint16_t key_id, const uint8_t* if (ATCA_SUCCESS == status) { - packet.param1 = 0x00; - packet.param2 = key_id; - // copy message digest into i/o buffer memcpy(packet.data, msg, ATCA_SHA256_DIGEST_SIZE); diff --git a/lib/calib/calib_write.c b/lib/calib/calib_write.c index e69731385..97d861196 100644 --- a/lib/calib/calib_write.c +++ b/lib/calib/calib_write.c @@ -642,6 +642,8 @@ ATCA_STATUS calib_ecc204_write_zone(ATCADevice device, uint8_t zone, uint16_t sl ATCA_STATUS status = ATCA_SUCCESS; uint16_t addr; + ((void)offset); + if ((NULL == device) && (NULL == data)) { status = ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer encountered"); @@ -675,7 +677,7 @@ ATCA_STATUS calib_ecc204_write_zone(ATCADevice device, uint8_t zone, uint16_t sl * * \return ATCA_SUCCESS on success, otherwise an error code */ -ATCA_STATUS calib_ecc204_write_config_zone(ATCADevice device, uint8_t* config_data) +ATCA_STATUS calib_ecc204_write_config_zone(ATCADevice device, const uint8_t* config_data) { ATCA_STATUS status = ATCA_SUCCESS; uint8_t slot = 1; @@ -870,6 +872,8 @@ ATCA_STATUS calib_ecc204_write_bytes_zone(ATCADevice device, uint8_t zone, uint1 block += 1; // Read next block data_idx += 1; // increment data index } + + return status; } #endif \ No newline at end of file diff --git a/lib/crypto/atca_crypto_hw_aes_cmac.c b/lib/crypto/atca_crypto_hw_aes_cmac.c index 21df725d0..3b28c85ad 100644 --- a/lib/crypto/atca_crypto_hw_aes_cmac.c +++ b/lib/crypto/atca_crypto_hw_aes_cmac.c @@ -91,8 +91,8 @@ ATCA_STATUS atcab_aes_cmac_init(atca_aes_cmac_ctx_t* ctx, uint16_t key_id, uint8 */ ATCA_STATUS atcab_aes_cmac_update(atca_aes_cmac_ctx_t* ctx, const uint8_t* data, uint32_t data_size) { - uint32_t rem_size = ATCA_AES128_BLOCK_SIZE - ctx->block_size; - uint32_t copy_size = data_size > rem_size ? rem_size : data_size; + uint32_t rem_size; + uint32_t copy_size; ATCA_STATUS status = ATCA_SUCCESS; uint8_t ciphertext[ATCA_AES128_BLOCK_SIZE]; uint32_t block_count; @@ -103,6 +103,9 @@ ATCA_STATUS atcab_aes_cmac_update(atca_aes_cmac_ctx_t* ctx, const uint8_t* data, return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); } + rem_size = ATCA_AES128_BLOCK_SIZE - ctx->block_size; + copy_size = data_size > rem_size ? rem_size : data_size; + memcpy(&ctx->block[ctx->block_size], data, copy_size); if (ctx->block_size + data_size < ATCA_AES128_BLOCK_SIZE + 1) diff --git a/lib/crypto/atca_crypto_pbkdf2.c b/lib/crypto/atca_crypto_pbkdf2.c new file mode 100644 index 000000000..2af4b6cba --- /dev/null +++ b/lib/crypto/atca_crypto_pbkdf2.c @@ -0,0 +1,195 @@ +/** + * \file + * \brief Implementation of the PBKDF2 algorithm for use in generating password + * hashes. + * + * \copyright (c) 2015-2020 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include "cryptoauthlib.h" + +/** \brief Calculate a PBKDF2 hash of a given password and salt + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcac_pbkdf2_sha256( + const uint32_t iter, /**< [in] Number of iterations of the algorithm to perform */ + const uint8_t * password, /**< [in] Password to hash */ + const size_t password_len, /**< [in] Length of the password bytes buffer */ + const uint8_t * salt, /**< [in] Salt bytes to use */ + const size_t salt_len, /**< [in] Length of the salt bytes buffer */ + uint8_t * result, /**< [out] Output buffer to hold the derived key */ + size_t result_len /**< [in] Length of the key to derive */ + ) +{ + ATCA_STATUS status = ATCA_BAD_PARAM; + atcac_hmac_sha256_ctx ctx; + uint32_t i, j; + uint32_t counter = 1; + uint8_t temp1_digest[ATCA_SHA256_DIGEST_SIZE]; + uint8_t temp2_digest[ATCA_SHA256_DIGEST_SIZE]; + + for (; 0 < result_len; counter++) + { + size_t temp_size = ATCA_SHA256_DIGEST_SIZE; + uint32_t temp_u32; + + if (ATCA_SUCCESS != (status = atcac_sha256_hmac_init(&ctx, password, (uint8_t)password_len))) + { + break; + } + + if (ATCA_SUCCESS != (status = atcac_sha256_hmac_update(&ctx, salt, salt_len))) + { + break; + } + + temp_u32 = ATCA_UINT32_HOST_TO_BE(counter); + if (ATCA_SUCCESS != (status = atcac_sha256_hmac_update(&ctx, (uint8_t*)&temp_u32, 4))) + { + break; + } + + if (ATCA_SUCCESS != (status = atcac_sha256_hmac_finish(&ctx, temp1_digest, &temp_size))) + { + break; + } + + memcpy(temp2_digest, temp1_digest, ATCA_SHA256_DIGEST_SIZE); + + for (i = 1; i < iter; i++) + { + if (ATCA_SUCCESS != (status = atcac_sha256_hmac_init(&ctx, password, (uint8_t)password_len))) + { + break; + } + + if (ATCA_SUCCESS != (status = atcac_sha256_hmac_update(&ctx, temp2_digest, ATCA_SHA256_DIGEST_SIZE))) + { + break; + } + + if (ATCA_SUCCESS != (status = atcac_sha256_hmac_finish(&ctx, temp2_digest, &temp_size))) + { + break; + } + + for (j = 0; j < ATCA_SHA256_DIGEST_SIZE; j++) + { + temp1_digest[j] ^= temp2_digest[j]; + } + } + + if (ATCA_SUCCESS == status) + { + size_t copy_len = (result_len < ATCA_SHA256_DIGEST_SIZE) ? result_len : ATCA_SHA256_DIGEST_SIZE; + memcpy(result, temp1_digest, copy_len); + + result_len -= copy_len; + result += copy_len; + } + } + return status; +} + +/** \brief Calculate a PBKDF2 password hash using a stored key inside a device. The key length is + * determined by the device being used. ECCx08: 32 bytes, TA100: 16-64 bytes + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_pbkdf2_sha256_ext( + ATCADevice device, /**< [in] Device context pointer */ + const uint32_t iter, /**< [in] Number of iterations of the algorithm to perform */ + const uint16_t slot, /**< [in] Slot/handle with a stored key (password) */ + const uint8_t* salt, /**< [in] Salt bytes to use */ + const size_t salt_len, /**< [in] Length of the salt bytes buffer */ + uint8_t* result, /**< [out] Output buffer to hold the derived key */ + size_t result_len /**< [in] Length of the key to derive */ + ) +{ + ATCA_STATUS status = ATCA_BAD_PARAM; + uint32_t i, j; + uint32_t counter = 1; + uint8_t temp1_digest[ATCA_SHA256_DIGEST_SIZE]; + uint8_t temp2_digest[ATCA_SHA256_DIGEST_SIZE]; + uint8_t message[ATCA_SHA256_BLOCK_SIZE]; + + for (; 0 < result_len; counter++) + { + uint32_t temp_u32; + size_t msg_len; + + temp_u32 = ATCA_UINT32_HOST_TO_BE(counter); + + memcpy(message, salt, salt_len); + memcpy(&message[salt_len], &temp_u32, 4); + msg_len = salt_len + 4; + + if (ATCA_SUCCESS != (status = ATCA_TRACE(atcab_sha_hmac_ext(device, message, msg_len, slot, temp1_digest, 0), ""))) + { + break; + } + + memcpy(temp2_digest, temp1_digest, ATCA_SHA256_DIGEST_SIZE); + + for (i = 1; i < iter; i++) + { + if (ATCA_SUCCESS != (status = ATCA_TRACE(atcab_sha_hmac_ext(device, temp2_digest, ATCA_SHA256_DIGEST_SIZE, slot, temp2_digest, 0), ""))) + { + break; + } + + for (j = 0; j < ATCA_SHA256_DIGEST_SIZE; j++) + { + temp1_digest[j] ^= temp2_digest[j]; + } + } + + if (ATCA_SUCCESS == status) + { + size_t copy_len = (result_len < ATCA_SHA256_DIGEST_SIZE) ? result_len : ATCA_SHA256_DIGEST_SIZE; + memcpy(result, temp1_digest, copy_len); + + result_len -= copy_len; + result += copy_len; + } + } + return status; +} + +/** \brief Calculate a PBKDF2 password hash using a stored key inside a device. The key length is + * determined by the device being used. ECCx08: 32 bytes, TA100: 16-64 bytes + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_pbkdf2_sha256( + const uint32_t iter, /**< [in] Number of iterations of the algorithm to perform */ + const uint16_t slot, /**< [in] Slot/handle with a stored key (password) */ + const uint8_t* salt, /**< [in] Salt bytes to use */ + const size_t salt_len, /**< [in] Length of the salt bytes buffer */ + uint8_t* result, /**< [out] Output buffer to hold the derived key */ + size_t result_len /**< [in] Length of the key to derive */ + ) +{ + return atcab_pbkdf2_sha256_ext(atcab_get_device(), iter, slot, salt, salt_len, result, result_len); +} diff --git a/lib/crypto/atca_crypto_sw.h b/lib/crypto/atca_crypto_sw.h index 85b098f5b..4c002abbb 100644 --- a/lib/crypto/atca_crypto_sw.h +++ b/lib/crypto/atca_crypto_sw.h @@ -119,6 +119,9 @@ typedef atca_wc_ctx atcac_pk_ctx; #define ATCA_ENABLE_SHA256_IMPL 1 #endif +#ifndef ATCA_ENABLE_RAND_IMPL +#define ATCA_ENABLE_RAND_IMPL 1 +#endif typedef struct { @@ -173,8 +176,10 @@ ATCA_STATUS atcac_aes_gcm_decrypt(atcac_aes_gcm_ctx* ctx, const uint8_t* ciphert size_t tag_len, const uint8_t* aad, const size_t aad_len, bool* is_verified); #endif +ATCA_STATUS atcac_pbkdf2_sha256(const uint32_t iter, const uint8_t* password, const size_t password_len, const uint8_t* salt, const size_t salt_len, uint8_t* result, size_t result_len); + #ifdef __cplusplus } #endif -#endif /* ATCA_CRYPTO_SW_H */ \ No newline at end of file +#endif /* ATCA_CRYPTO_SW_H */ diff --git a/lib/crypto/atca_crypto_sw_ecdsa.c b/lib/crypto/atca_crypto_sw_ecdsa.c index 46c95e168..137007757 100644 --- a/lib/crypto/atca_crypto_sw_ecdsa.c +++ b/lib/crypto/atca_crypto_sw_ecdsa.c @@ -40,5 +40,9 @@ int atcac_sw_ecdsa_verify_p256(const uint8_t msg[ATCA_ECC_P256_FIELD_SIZE], const uint8_t signature[ATCA_ECC_P256_SIGNATURE_SIZE], const uint8_t public_key[ATCA_ECC_P256_PUBLIC_KEY_SIZE]) { + (void)msg; + (void)signature; + (void)public_key; + return ATCA_UNIMPLEMENTED; -} \ No newline at end of file +} diff --git a/lib/crypto/atca_crypto_sw_rand.c b/lib/crypto/atca_crypto_sw_rand.c index 5ee302bd4..be25677d3 100644 --- a/lib/crypto/atca_crypto_sw_rand.c +++ b/lib/crypto/atca_crypto_sw_rand.c @@ -25,6 +25,10 @@ * THIS SOFTWARE. */ +#include "cryptoauthlib.h" + +#ifdef ATCA_ENABLE_RAND_IMPL + #include "atca_crypto_sw_rand.h" /** \brief return software generated random number and the function is currently not implemented @@ -36,4 +40,6 @@ int atcac_sw_random(uint8_t* data, size_t data_size) { return ATCA_UNIMPLEMENTED; -} \ No newline at end of file +} + +#endif diff --git a/lib/crypto/atca_crypto_sw_sha2.c b/lib/crypto/atca_crypto_sw_sha2.c index f1468d53f..633257cb0 100644 --- a/lib/crypto/atca_crypto_sw_sha2.c +++ b/lib/crypto/atca_crypto_sw_sha2.c @@ -98,7 +98,7 @@ ATCA_STATUS atcac_sha256_hmac_init( { (void)atcac_sw_sha2_256_init(&ctx->sha256_ctx); (void)atcac_sw_sha2_256_update(&ctx->sha256_ctx, key, klen); - status = atcac_sw_sha2_256_finish(&ctx->sha256_ctx, ctx->ipad); + status = (ATCA_STATUS)atcac_sw_sha2_256_finish(&ctx->sha256_ctx, ctx->ipad); klen = ATCA_SHA2_256_DIGEST_SIZE; } @@ -117,7 +117,7 @@ ATCA_STATUS atcac_sha256_hmac_init( } (void)atcac_sw_sha2_256_init(&ctx->sha256_ctx); - status = atcac_sw_sha2_256_update(&ctx->sha256_ctx, ctx->ipad, ATCA_SHA2_256_BLOCK_SIZE); + status = (ATCA_STATUS)atcac_sw_sha2_256_update(&ctx->sha256_ctx, ctx->ipad, ATCA_SHA2_256_BLOCK_SIZE); } } @@ -135,7 +135,7 @@ ATCA_STATUS atcac_sha256_hmac_update( size_t data_size /**< [in] length of input data */ ) { - return atcac_sw_sha2_256_update(&ctx->sha256_ctx, data, data_size); + return (ATCA_STATUS)atcac_sw_sha2_256_update(&ctx->sha256_ctx, data, data_size); } /** \brief Finish HMAC calculation and clear the HMAC context @@ -154,14 +154,14 @@ ATCA_STATUS atcac_sha256_hmac_finish( { uint8_t temp_dig[ATCA_SHA2_256_DIGEST_SIZE]; - status = atcac_sw_sha2_256_finish(&ctx->sha256_ctx, temp_dig); + status = (ATCA_STATUS)atcac_sw_sha2_256_finish(&ctx->sha256_ctx, temp_dig); if (ATCA_SUCCESS == status) { (void)atcac_sw_sha2_256_init(&ctx->sha256_ctx); (void)atcac_sw_sha2_256_update(&ctx->sha256_ctx, ctx->opad, ATCA_SHA2_256_BLOCK_SIZE); (void)atcac_sw_sha2_256_update(&ctx->sha256_ctx, temp_dig, ATCA_SHA2_256_DIGEST_SIZE); - status = atcac_sw_sha2_256_finish(&ctx->sha256_ctx, digest); + status = (ATCA_STATUS)atcac_sw_sha2_256_finish(&ctx->sha256_ctx, digest); } } return status; diff --git a/lib/hal/atca_hal.c b/lib/hal/atca_hal.c index a0e063ec9..92f9a9403 100644 --- a/lib/hal/atca_hal.c +++ b/lib/hal/atca_hal.c @@ -148,7 +148,7 @@ static atca_hal_list_entry_t atca_registered_hal_list[ATCA_MAX_HAL_CACHE] = { #ifdef ATCA_HAL_I2C { ATCA_I2C_IFACE, &hal_i2c, NULL }, #endif -#ifdef ATCA_HAL_SWI +#ifdef ATCA_HAL_SWI_UART { ATCA_SWI_IFACE, &hal_swi_uart, &hal_uart }, #endif #ifdef ATCA_HAL_KIT_UART @@ -182,7 +182,7 @@ static ATCA_STATUS hal_iface_get_registered(ATCAIfaceType iface_type, ATCAHAL_t* if (hal && phy) { - int i; + size_t i; for (i = 0; i < atca_registered_hal_list_size; i++) { if (iface_type == atca_registered_hal_list[i].iface_type) @@ -217,8 +217,8 @@ static ATCA_STATUS hal_iface_set_registered(ATCAIfaceType iface_type, ATCAHAL_t* if (hal) { - int i; - int empty = atca_registered_hal_list_size; + size_t i; + size_t empty = atca_registered_hal_list_size; for (i = 0; i < atca_registered_hal_list_size; i++) { if (iface_type == atca_registered_hal_list[i].iface_type) diff --git a/lib/hal/atca_hal.h b/lib/hal/atca_hal.h index 50175592b..121c0bbd2 100644 --- a/lib/hal/atca_hal.h +++ b/lib/hal/atca_hal.h @@ -78,7 +78,7 @@ ATCA_STATUS hal_i2c_sleep(ATCAIface iface); ATCA_STATUS hal_i2c_release(void *hal_data); #endif -#ifdef ATCA_HAL_SWI +#ifdef ATCA_HAL_SWI_UART ATCA_STATUS hal_swi_init(ATCAIface iface, ATCAIfaceCfg *cfg); ATCA_STATUS hal_swi_post_init(ATCAIface iface); ATCA_STATUS hal_swi_send(ATCAIface iface, uint8_t word_address, uint8_t *txdata, int txlength); @@ -116,7 +116,7 @@ ATCA_STATUS hal_uart_wake(ATCAIface iface); ATCA_STATUS hal_uart_idle(ATCAIface iface); ATCA_STATUS hal_uart_sleep(ATCAIface iface); #endif -ATCA_STATUS hal_uart_release(ATCAIface iface); +ATCA_STATUS hal_uart_release(void *hal_data); #endif #ifdef ATCA_HAL_SPI @@ -177,7 +177,8 @@ typedef enum ATCA_HAL_CONTROL_RESET = 3, ATCA_HAL_CONTROL_SELECT = 4, ATCA_HAL_CONTROL_DESELECT = 5, - ATCA_HAL_CHANGE_BAUD = 6 + ATCA_HAL_CHANGE_BAUD = 6, + ATCA_HAL_FLUSH_BUFFER = 7 } ATCA_HAL_CONTROL; /** \brief Timer API for legacy implementations */ diff --git a/lib/hal/hal_all_platforms_kit_hidapi.c b/lib/hal/hal_all_platforms_kit_hidapi.c index 5de4fa2b7..51f00b6e9 100644 --- a/lib/hal/hal_all_platforms_kit_hidapi.c +++ b/lib/hal/hal_all_platforms_kit_hidapi.c @@ -40,8 +40,6 @@ * @{ */ -#define HID_PACKET_MAX 512 //! Maximum number of bytes for a HID send/receive packet (typically 64) - /** \brief HAL implementation of Kit USB HID init * \param[in] hal pointer to HAL specific data that is maintained by this HAL * \param[in] cfg pointer to HAL specific configuration data that is used to initialize this HAL @@ -89,10 +87,7 @@ ATCA_STATUS hal_kit_hid_send(ATCAIface iface, uint8_t word_address, uint8_t* txd { ATCAIfaceCfg *cfg = atgetifacecfg(iface); hid_device* pHid = (hid_device*)atgetifacehaldat(iface); - int bytes_written = 0; - int bytes_left; - int bytes_to_send; - uint8_t buffer[HID_PACKET_MAX]; + int bytes_written; if ((txdata == NULL) || (cfg == NULL) || (pHid == NULL)) { @@ -103,30 +98,10 @@ ATCA_STATUS hal_kit_hid_send(ATCAIface iface, uint8_t word_address, uint8_t* txd printf("HID layer: Write: %s", txdata); #endif - //To avoid ERROR_INVALID_USER_BUFFER on Windows - bytes_left = txlength; - while (bytes_left > 0) + bytes_written = hid_write(pHid, txdata, (size_t)cfg->atcahid.packetsize + 1); + if (bytes_written != cfg->atcahid.packetsize + 1) { - memset(buffer, 0, (HID_PACKET_MAX)); - - if (bytes_left >= (int)cfg->atcahid.packetsize) - { - bytes_to_send = cfg->atcahid.packetsize; - } - else - { - bytes_to_send = bytes_left; - } - - memcpy(&buffer[1], &txdata[(txlength - bytes_left)], bytes_to_send); - - bytes_written = hid_write(pHid, buffer, (size_t)cfg->atcahid.packetsize + 1); - if (bytes_written != cfg->atcahid.packetsize + 1) - { - return ATCA_TX_FAIL; - } - - bytes_left -= bytes_to_send; + return ATCA_TX_FAIL; } return ATCA_SUCCESS; @@ -141,44 +116,17 @@ ATCA_STATUS hal_kit_hid_send(ATCAIface iface, uint8_t word_address, uint8_t* txd */ ATCA_STATUS hal_kit_hid_receive(ATCAIface iface, uint8_t word_address, uint8_t* rxdata, uint16_t* rxsize) { - ATCAIfaceCfg *cfg = atgetifacecfg(iface); hid_device* pHid = (hid_device*)atgetifacehaldat(iface); - size_t bytes_read = 0; - size_t total_bytes_read = 0; - size_t bytes_to_read = *rxsize; - char *location; - if ((rxdata == NULL) || (rxsize == NULL) || (cfg == NULL) || (pHid == NULL)) + if ((rxdata == NULL) || (rxsize == NULL) || (pHid == NULL)) { return ATCA_BAD_PARAM; } - bytes_to_read--; - - // Receive the data from the kit USB device - do - { - bytes_read = hid_read(pHid, &rxdata[total_bytes_read], bytes_to_read); - if (bytes_read == -1) - { - return ATCA_RX_FAIL; - } - - location = memchr(&rxdata[total_bytes_read], '\n', bytes_read); - - total_bytes_read += bytes_read; - bytes_to_read -= bytes_read; - } - while (!location && 0 < bytes_to_read); - - // Save the total bytes read - if (location != NULL) - { - *rxsize = (int)(location - (char*)rxdata); - } - else + *rxsize = (uint16_t)hid_read(pHid, rxdata, (size_t)*rxsize); + if (*rxsize == -1) { - *rxsize = (int)total_bytes_read; + return ATCA_RX_FAIL; } #ifdef KIT_DEBUG diff --git a/lib/hal/hal_freertos.c b/lib/hal/hal_freertos.c index e5c7581b0..8303922ba 100644 --- a/lib/hal/hal_freertos.c +++ b/lib/hal/hal_freertos.c @@ -43,6 +43,20 @@ * @{ */ +#if !defined(ATCA_PLATFORM_MALLOC) +void* hal_malloc(size_t size) +{ + return pvPortMalloc(size); +} +#endif + +#if !defined(ATCA_PLATFORM_FREE) +void hal_free(void* ptr) +{ + vPortFree(ptr); +} +#endif + /** * \brief This function delays for a number of milliseconds. * diff --git a/lib/hal/hal_linux_i2c_userspace.c b/lib/hal/hal_linux_i2c_userspace.c index da3212b6e..6d6c3d4f3 100644 --- a/lib/hal/hal_linux_i2c_userspace.c +++ b/lib/hal/hal_linux_i2c_userspace.c @@ -113,6 +113,7 @@ ATCA_STATUS hal_i2c_init(ATCAIface iface, ATCAIfaceCfg* cfg) */ ATCA_STATUS hal_i2c_post_init(ATCAIface iface) { + ((void)iface); return ATCA_SUCCESS; } @@ -126,10 +127,14 @@ ATCA_STATUS hal_i2c_post_init(ATCAIface iface) ATCA_STATUS hal_i2c_send(ATCAIface iface, uint8_t address, uint8_t *txdata, int txlength) { - ATCAIfaceCfg *cfg = atgetifacecfg(iface); atca_i2c_host_t * hal_data = (atca_i2c_host_t*)atgetifacehaldat(iface); int f_i2c; // I2C file descriptor + if (!hal_data) + { + return ATCA_NOT_INITIALIZED; + } + // Initiate I2C communication if ( (f_i2c = open(hal_data->i2c_file, O_RDWR)) < 0) { @@ -156,18 +161,22 @@ ATCA_STATUS hal_i2c_send(ATCAIface iface, uint8_t address, uint8_t *txdata, int /** \brief HAL implementation of I2C receive function * \param[in] iface Device to interact with. - * \param[in] word_address device transaction type + * \param[in] address device address * \param[out] rxdata Data received will be returned here. * \param[in,out] rxlength As input, the size of the rxdata buffer. * As output, the number of bytes received. * \return ATCA_SUCCESS on success, otherwise an error code. */ -ATCA_STATUS hal_i2c_receive(ATCAIface iface, uint8_t word_address, uint8_t *rxdata, uint16_t *rxlength) +ATCA_STATUS hal_i2c_receive(ATCAIface iface, uint8_t address, uint8_t *rxdata, uint16_t *rxlength) { - ATCAIfaceCfg *cfg = atgetifacecfg(iface); atca_i2c_host_t * hal_data = (atca_i2c_host_t*)atgetifacehaldat(iface); int f_i2c; // I2C file descriptor + if (!hal_data) + { + return ATCA_NOT_INITIALIZED; + } + // Initiate I2C communication if ( (f_i2c = open(hal_data->i2c_file, O_RDWR)) < 0) { @@ -175,7 +184,7 @@ ATCA_STATUS hal_i2c_receive(ATCAIface iface, uint8_t word_address, uint8_t *rxda } // Set Device Address - if (ioctl(f_i2c, I2C_SLAVE, cfg->atcai2c.address >> 1) < 0) + if (ioctl(f_i2c, I2C_SLAVE, address >> 1) < 0) { close(f_i2c); return ATCA_COMM_FAIL; @@ -200,6 +209,7 @@ ATCA_STATUS hal_i2c_receive(ATCAIface iface, uint8_t word_address, uint8_t *rxda */ ATCA_STATUS hal_i2c_control(ATCAIface iface, uint8_t option, void* param, size_t paramlen) { + (void)option; (void)param; (void)paramlen; diff --git a/lib/hal/kit_protocol.c b/lib/hal/kit_protocol.c index bf2c7a38f..53efbf975 100644 --- a/lib/hal/kit_protocol.c +++ b/lib/hal/kit_protocol.c @@ -110,14 +110,62 @@ const char * kit_interface_from_kittype(ATCAKitType kittype) */ ATCA_STATUS kit_phy_send(ATCAIface iface, uint8_t* txdata, int txlength) { - if (iface && iface->phy && iface->phy->halsend) + ATCAIfaceCfg *cfg = atgetifacecfg(iface); + int bytes_written = 0; + int bytes_left = 0; + int bytes_to_send = 0; + int packetsize = 0; + uint8_t buffer[512]; //! Maximum number of bytes for a HID send/receive packet (typically 64) + ATCA_STATUS status = ATCA_SUCCESS; + + if ((NULL == cfg) || (NULL == iface) || (NULL == iface->phy) || + (NULL == iface->phy->halsend) || (NULL == txdata)) { - return iface->phy->halsend(iface, 0xFF, txdata, txlength); + return ATCA_BAD_PARAM; + } + + if (ATCA_HID_IFACE == iface->mIfaceCFG->iface_type) + { +#ifdef ATCA_HAL_KIT_HID + packetsize = (int)cfg->atcahid.packetsize; +#endif + } + else if (ATCA_UART_IFACE == iface->mIfaceCFG->iface_type) + { +#ifdef ATCA_HAL_KIT_UART + packetsize = 1; +#endif } else { return ATCA_BAD_PARAM; } + + bytes_left = txlength; + while (bytes_left > 0) + { + memset(buffer, 0, sizeof(buffer)); + + if (bytes_left >= packetsize) + { + bytes_to_send = packetsize; + } + else + { + bytes_to_send = bytes_left; + } + + memcpy(&buffer[1], &txdata[(txlength - bytes_left)], bytes_to_send); + + if (ATCA_SUCCESS != (status = iface->phy->halsend(iface, 0xFF, buffer, packetsize))) + { + break; + } + + bytes_left -= bytes_to_send; + } + + return status; } /** \brief HAL implementation of kit protocol send over USB HID @@ -129,24 +177,58 @@ ATCA_STATUS kit_phy_send(ATCAIface iface, uint8_t* txdata, int txlength) ATCA_STATUS kit_phy_receive(ATCAIface iface, uint8_t* rxdata, int* rxsize) { ATCA_STATUS status = ATCA_BAD_PARAM; + size_t total_bytes_read = 0; + size_t bytes_to_read = 0; + char *location; + uint16_t rxlen; - if (iface && iface->phy && iface->phy->halreceive && rxsize) + if ((NULL == iface) || (NULL == iface->phy) || (NULL == iface->phy->halreceive) || + (NULL == rxdata) || (NULL == rxsize)) { - uint16_t rxlen = (uint16_t)*rxsize; - if (ATCA_SUCCESS == (status = iface->phy->halreceive(iface, 0, rxdata, &rxlen))) + return status; + } + + bytes_to_read = (size_t)*rxsize; + rxlen = (uint16_t)bytes_to_read--; + + do + { + if (ATCA_SUCCESS != (status = iface->phy->halreceive(iface, 0x00, &rxdata[total_bytes_read], &rxlen))) { - *rxsize = rxlen; + break; } + + location = memchr(&rxdata[total_bytes_read], '\n', (size_t)rxlen); + + total_bytes_read += rxlen; + bytes_to_read -= rxlen; + } + while ((NULL == location) && (0 < bytes_to_read)); - return status; + if (ATCA_SUCCESS != status) + { + return status; + } + + // Save the total bytes read + if (location != NULL) + { + *rxsize = (int)(location - (char*)rxdata); + } + else + { + *rxsize = (int)total_bytes_read; + } + + return ATCA_SUCCESS; } /** \brief HAL implementation of kit protocol init. This function calls back to the physical protocol to send the bytes * \param[in] iface instance * \return ATCA_SUCCESS on success, otherwise an error code. */ -ATCA_STATUS kit_init(ATCAIface iface) +ATCA_STATUS kit_init(ATCAIface iface, ATCAIfaceCfg* cfg) { ATCA_STATUS status = ATCA_SUCCESS; const char kit_device[] = "board:device(%02X)\n"; @@ -162,6 +244,8 @@ ATCA_STATUS kit_init(ATCAIface iface) int i; int address; + ((void)cfg); + device_match = kit_id_from_devtype(iface->mIfaceCFG->devtype); interface_match = kit_interface_from_kittype(iface->mIfaceCFG->atcahid.dev_interface); diff --git a/lib/hal/kit_protocol.h b/lib/hal/kit_protocol.h index b2bea0ec1..9af9cae6f 100644 --- a/lib/hal/kit_protocol.h +++ b/lib/hal/kit_protocol.h @@ -52,7 +52,7 @@ extern "C" { #endif -ATCA_STATUS kit_init(ATCAIface iface); +ATCA_STATUS kit_init(ATCAIface iface, ATCAIfaceCfg* cfg); ATCA_STATUS kit_post_init(ATCAIface iface); ATCA_STATUS kit_send(ATCAIface iface, uint8_t word_address, uint8_t* txdata, int txlength); ATCA_STATUS kit_receive(ATCAIface iface, uint8_t word_address, uint8_t* rxdata, uint16_t* rxsize); diff --git a/lib/host/atca_host.c b/lib/host/atca_host.c index cd03a306d..2f60acd17 100644 --- a/lib/host/atca_host.c +++ b/lib/host/atca_host.c @@ -1344,7 +1344,7 @@ ATCA_STATUS atcah_decrypt(struct atca_decrypt_in_out *param) */ ATCA_STATUS atcah_sha256(int32_t len, const uint8_t *message, uint8_t *digest) { - return atcac_sw_sha2_256(message, len, digest); + return (ATCA_STATUS)atcac_sw_sha2_256(message, len, digest); } /** \brief Calculate the PubKey digest created by GenKey and saved to TempKey. @@ -1541,7 +1541,7 @@ ATCA_STATUS atcah_sign_internal_msg(ATCADeviceType device_type, struct atca_sign } if (param->digest) { - return atcac_sw_sha2_256(msg, sizeof(msg), param->digest); + return (ATCA_STATUS)atcac_sw_sha2_256(msg, sizeof(msg), param->digest); } else { diff --git a/lib/jwt/atca_jwt.c b/lib/jwt/atca_jwt.c index 7c5522ce3..370b7cc2e 100644 --- a/lib/jwt/atca_jwt.c +++ b/lib/jwt/atca_jwt.c @@ -172,7 +172,7 @@ ATCA_STATUS atca_jwt_finalize( } /* Create digest of the message store and store in the buffer */ - status = atcac_sw_sha2_256((const uint8_t*)jwt->buf, jwt->cur, (uint8_t*)(jwt->buf + jwt->buflen - 32)); + status = (ATCA_STATUS)atcac_sw_sha2_256((const uint8_t*)jwt->buf, jwt->cur, (uint8_t*)(jwt->buf + jwt->buflen - 32)); if (ATCA_SUCCESS != status) { return status; @@ -266,7 +266,7 @@ ATCA_STATUS atca_jwt_add_claim_numeric( if (0 < written && written < remaining) { jwt->cur += written; - return 0; + return ATCA_SUCCESS; } else { @@ -325,7 +325,7 @@ ATCA_STATUS atca_jwt_verify( } /* Digest the token */ - if (ATCA_SUCCESS != (status = atcac_sw_sha2_256((const uint8_t*)buf, pStr - buf - 1, digest))) + if (ATCA_SUCCESS != (status = (ATCA_STATUS)atcac_sw_sha2_256((const uint8_t*)buf, pStr - buf - 1, digest))) { break; } diff --git a/lib/mbedtls/atca_mbedtls_ecdh.c b/lib/mbedtls/atca_mbedtls_ecdh.c index f73a1df2d..952da581f 100644 --- a/lib/mbedtls/atca_mbedtls_ecdh.c +++ b/lib/mbedtls/atca_mbedtls_ecdh.c @@ -133,7 +133,7 @@ int mbedtls_ecdh_compute_shared(mbedtls_ecp_group *grp, mbedtls_mpi *z, if (!ret) { slotid = *(uint16_t*)d->p; - if (ATECC608 == atcab_get_device()->mIface->mIfaceCFG->devtype) + if (ATECC608 == atcab_get_device_type()) { ret = atca_mbedtls_ecdh_ioprot_cb(secret); if (!ret) diff --git a/lib/mbedtls/atca_mbedtls_ecdsa.c b/lib/mbedtls/atca_mbedtls_ecdsa.c index 653f241d1..0b6ae3ab8 100644 --- a/lib/mbedtls/atca_mbedtls_ecdsa.c +++ b/lib/mbedtls/atca_mbedtls_ecdsa.c @@ -35,13 +35,49 @@ #if defined(MBEDTLS_ECDSA_C) -#include "mbedtls/ecdsa.h" - /* Cryptoauthlib Includes */ #include "cryptoauthlib.h" #include "atca_basic.h" #include +#include "mbedtls/atca_mbedtls_wrap.h" +#include "mbedtls/ecdsa.h" + + +int atca_mbedtls_ecdsa_sign(const mbedtls_mpi* d, mbedtls_mpi* r, mbedtls_mpi* s, + const unsigned char* msg, size_t msg_len) +{ + int ret = 0; + + if (d && r && s && msg && ATCA_SHA256_DIGEST_SIZE <= msg_len) + { + atca_mbedtls_eckey_t key_info; + uint8_t raw_sig[ATCA_ECCP256_SIG_SIZE]; + + ret = mbedtls_mpi_write_binary(d, (unsigned char*)&key_info, sizeof(atca_mbedtls_eckey_t)); + + if (!ret) + { + if (ATCA_SUCCESS != atcab_sign_ext(key_info.device, key_info.handle, msg, raw_sig)) + { + ret = -1; + } + } + + if (!ret) + { + ret = mbedtls_mpi_read_binary(r, raw_sig, ATCA_ECCP256_SIG_SIZE / 2); + } + + if (!ret) + { + ret = mbedtls_mpi_read_binary(s, &raw_sig[ATCA_ECCP256_SIG_SIZE / 2], ATCA_ECCP256_SIG_SIZE / 2); + } + } + + return ret; +} + #ifdef MBEDTLS_ECDSA_SIGN_ALT /* @@ -52,36 +88,13 @@ int mbedtls_ecdsa_sign(mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s, const mbedtls_mpi *d, const unsigned char *buf, size_t blen, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) { - int ret = 0; - uint8_t raw_sig[ATCA_SIG_SIZE]; - + ((void)grp); ((void)f_rng); ((void)p_rng); - if (ATCA_KEY_SIZE > blen || !d || !d->p) - { - ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA; - } - - if (!ret) - { - ret = atcab_sign(*(uint16_t*)d->p, buf, raw_sig); - } - - if (!ret) - { - ret = mbedtls_mpi_read_binary(r, raw_sig, ATCA_SIG_SIZE / 2); - } - - if (!ret) - { - ret = mbedtls_mpi_read_binary(s, &raw_sig[ATCA_SIG_SIZE / 2], ATCA_SIG_SIZE / 2); - } - - return ret; + return atca_mbedtls_ecdsa_sign(d, r, s, buf, blen); } - -#endif /* MBEDTLS_ECDSA_SIGN_ALT */ +#endif #ifdef MBEDTLS_ECDSA_VERIFY_ALT /* @@ -95,7 +108,6 @@ int mbedtls_ecdsa_verify(mbedtls_ecp_group *grp, { int ret = 0; uint8_t raw_sig[ATCA_SIG_SIZE]; - uint8_t public_key[ATCA_PUB_KEY_SIZE]; bool verified = false; if (!grp || !buf || !Q || !r || !s) @@ -108,16 +120,6 @@ int mbedtls_ecdsa_verify(mbedtls_ecp_group *grp, ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; } - /* Convert the public key to it's uncompressed binary */ - if (!ret) - { - ret = mbedtls_mpi_write_binary(&(Q->X), public_key, ATCA_PUB_KEY_SIZE / 2); - } - if (!ret) - { - ret = mbedtls_mpi_write_binary(&(Q->Y), &public_key[ATCA_PUB_KEY_SIZE / 2], ATCA_PUB_KEY_SIZE / 2); - } - /* Convert the signature to binary */ if (!ret) { @@ -128,13 +130,46 @@ int mbedtls_ecdsa_verify(mbedtls_ecp_group *grp, ret = mbedtls_mpi_write_binary(s, &raw_sig[ATCA_SIG_SIZE / 2], ATCA_SIG_SIZE / 2); } - if (!ret) + if (Q->Z.n == 1) + { + uint8_t public_key[ATCA_PUB_KEY_SIZE]; + + /* Convert the public key to it's uncompressed binary */ + if (!ret) + { + ret = mbedtls_mpi_write_binary(&(Q->X), public_key, ATCA_PUB_KEY_SIZE / 2); + } + if (!ret) + { + ret = mbedtls_mpi_write_binary(&(Q->Y), &public_key[ATCA_PUB_KEY_SIZE / 2], ATCA_PUB_KEY_SIZE / 2); + } + + if (!ret) + { + ret = atcab_verify_extern(buf, raw_sig, public_key, &verified); + + if (!ret && !verified) + { + ret = MBEDTLS_ERR_ECP_VERIFY_FAILED; + } + } + } + else { - ret = atcab_verify_extern(buf, raw_sig, public_key, &verified); + atca_mbedtls_eckey_t key_info; + if (!ret) + { + ret = mbedtls_mpi_write_binary(&Q->Z, (unsigned char*)&key_info, sizeof(atca_mbedtls_eckey_t)); + } - if (!ret && !verified) + if (!ret) { - ret = MBEDTLS_ERR_ECP_VERIFY_FAILED; + ret = calib_verify_stored(key_info.device, buf, raw_sig, key_info.handle, &verified); + + if (!ret && !verified) + { + ret = MBEDTLS_ERR_ECP_VERIFY_FAILED; + } } } diff --git a/lib/mbedtls/atca_mbedtls_wrap.c b/lib/mbedtls/atca_mbedtls_wrap.c index 853802580..159c55fb3 100644 --- a/lib/mbedtls/atca_mbedtls_wrap.c +++ b/lib/mbedtls/atca_mbedtls_wrap.c @@ -43,21 +43,36 @@ #endif #include "mbedtls/cmac.h" +#include "mbedtls/ctr_drbg.h" #include "mbedtls/pk.h" #include "mbedtls/ecdh.h" #include "mbedtls/ecp.h" +#include "mbedtls/entropy.h" #include "mbedtls/bignum.h" #include "mbedtls/x509_crt.h" /* Cryptoauthlib Includes */ #include "cryptoauthlib.h" +#include "atca_mbedtls_wrap.h" +#include "atca_mbedtls_patch.h" + #include "crypto/atca_crypto_sw.h" #if ATCA_CA_SUPPORT #include "atcacert/atcacert_client.h" #include "atcacert/atcacert_def.h" #endif +/** \brief Return Random Bytes + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +int atcac_sw_random(uint8_t* data, size_t data_size) +{ + return mbedtls_ctr_drbg_random(mbedtls_entropy_func, data, data_size); +} + + /** \brief Update the GCM context with additional authentication data (AAD) * * \return ATCA_SUCCESS on success, otherwise an error code. @@ -157,13 +172,7 @@ ATCA_STATUS atcac_aes_gcm_encrypt_finish( if (ctx) { - size_t outlen = 0; - int ret = mbedtls_cipher_finish(ctx, NULL, &outlen); - - if (!ret) - { - ret = mbedtls_cipher_write_tag(ctx, tag, tag_len); - } + int ret = mbedtls_cipher_write_tag(ctx, tag, tag_len); mbedtls_cipher_free(ctx); @@ -253,15 +262,9 @@ ATCA_STATUS atcac_aes_gcm_decrypt_finish( if (ctx && is_verified) { int ret; - size_t outlen = 0; *is_verified = false; - ret = mbedtls_cipher_finish(ctx, NULL, &outlen); - - if (!ret) - { - ret = mbedtls_cipher_check_tag(ctx, tag, tag_len); - } + ret = mbedtls_cipher_check_tag(ctx, tag, tag_len); if (!ret) { @@ -569,6 +572,8 @@ ATCA_STATUS atcac_pk_init( { ATCA_STATUS status = ATCA_BAD_PARAM; + (void)key_type; + if (ctx) { int ret; @@ -855,12 +860,6 @@ ATCA_STATUS atcac_pk_derive( #include "mbedtls/pk_internal.h" #include "atcacert/atcacert_der.h" -typedef struct atca_mbedtls_eckey_s -{ - ATCADevice device; - uint16_t handle; -} atca_mbedtls_eckey_t; - static size_t atca_mbedtls_eckey_get_bitlen(const void * ctx) { return mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)->get_bitlen(ctx); @@ -875,9 +874,15 @@ static int atca_mbedtls_eckey_verify(void *ctx, mbedtls_md_type_t md_alg, const unsigned char *hash, size_t hash_len, const unsigned char *sig, size_t sig_len) { +#ifdef MBEDTLS_ECDSA_VERIFY_ALT + return mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)->verify_func(ctx, md_alg, hash, hash_len, sig, sig_len); +#else int ret = -1; mbedtls_ecp_keypair *ecp = (mbedtls_ecp_keypair*)ctx; + (void)md_alg; + (void)hash_len; + if (ecp && hash && sig) { mbedtls_mpi r, s; @@ -928,14 +933,27 @@ static int atca_mbedtls_eckey_verify(void *ctx, mbedtls_md_type_t md_alg, if (!ret) { bool is_verified = false; - if (ATCA_SUCCESS == atcab_verify_stored_ext(key_info.device, hash, signature, key_info.handle, &is_verified)) + + // if (0x01 & key_info.flags) { - if (is_verified) + uint8_t public_key[ATCA_ECCP256_PUBKEY_SIZE]; + if (0 == (ret = mbedtls_mpi_write_binary(&ecp->Q.X, public_key, ATCA_ECCP256_PUBKEY_SIZE / 2))) { - ret = 0; + if (0 == (ret = mbedtls_mpi_write_binary(&ecp->Q.Y, &public_key[ATCA_ECCP256_PUBKEY_SIZE / 2], ATCA_ECCP256_PUBKEY_SIZE / 2))) + { + ret = atcab_verify_extern_ext(key_info.device, hash, signature, public_key, &is_verified); + } } } - ret = is_verified ? 0 : -1; +// else +// { +// ret = atcab_verify_stored_ext(key_info.device, hash, signature, key_info.handle, &is_verified); +// } + + if (ATCA_SUCCESS == ret) + { + ret = is_verified ? 0 : -1; + } } mbedtls_mpi_free(&r); @@ -943,6 +961,7 @@ static int atca_mbedtls_eckey_verify(void *ctx, mbedtls_md_type_t md_alg, } return ret; +#endif } static int atca_mbedtls_eckey_sign(void *ctx, mbedtls_md_type_t md_alg, @@ -954,35 +973,26 @@ static int atca_mbedtls_eckey_sign(void *ctx, mbedtls_md_type_t md_alg, int ret = -1; mbedtls_ecp_keypair *ecp = (mbedtls_ecp_keypair*)ctx; + ((void)md_alg); + ((void)f_rng); + ((void)p_rng); + if (ecp && hash && sig && sig_len) { mbedtls_mpi r, s; - atca_mbedtls_eckey_t key_info; - uint8_t signature[75]; - ret = mbedtls_mpi_write_binary(&ecp->d, (unsigned char*)&key_info, sizeof(atca_mbedtls_eckey_t)); + mbedtls_mpi_init(&r); + mbedtls_mpi_init(&s); - if (!ret) - { - if (ATCA_SUCCESS != atcab_sign_ext(key_info.device, key_info.handle, hash, &signature[10])) - { - ret = -1; - } - } + ret = atca_mbedtls_ecdsa_sign(&ecp->d, &r, &s, hash, hash_len); if (!ret) { - ret = atcacert_der_enc_ecdsa_sig_value(&signature[10], signature, sig_len); - + ret = mbedtls_ecdsa_signature_to_asn1(&r, &s, sig, sig_len); } - if (!ret) - { - /* atcacert_der_enc_ecdsa_sig_value add the outer tag info so we need to not copy it - to the output buffer for mbedtls */ - *sig_len -= 3; - memcpy(sig, &signature[3], *sig_len); - } + mbedtls_mpi_free(&r); + mbedtls_mpi_free(&s); } return ret; } @@ -999,12 +1009,12 @@ static void * atca_mbedtls_eckey_alloc(void) static void atca_mbedtls_eckey_free(void * ctx) { - return mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)->ctx_free_func(ctx); + mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)->ctx_free_func(ctx); } static void atca_mbedtls_eckey_debug(const void *ctx, mbedtls_pk_debug_item *items) { - return mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)->debug_func(ctx, items); + mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)->debug_func(ctx, items); } const mbedtls_pk_info_t atca_mbedtls_eckey_info = { @@ -1046,6 +1056,7 @@ int atca_mbedtls_pk_init_ext(ATCADevice device, mbedtls_pk_context * pkey, const uint8_t public_key[ATCA_ECCP256_SIG_SIZE]; mbedtls_ecp_keypair * ecp = NULL; uint8_t temp = 1; + bool is_private = false; if (!pkey) { @@ -1071,32 +1082,57 @@ int atca_mbedtls_pk_init_ext(ATCADevice device, mbedtls_pk_context * pkey, const if (!ret) { - ret = atcab_get_pubkey_ext(device, slotid, public_key); + ret = atcab_is_private_ext(device, slotid, &is_private); } if (!ret) { - ret = mbedtls_mpi_read_binary(&(ecp->Q.X), public_key, ATCA_ECCP256_SIG_SIZE / 2); + if (is_private) + { + ret = atcab_get_pubkey_ext(device, slotid, public_key); + } + else + { + ret = atcab_read_pubkey_ext(device, slotid, public_key); + } } if (!ret) { - ret = mbedtls_mpi_read_binary(&(ecp->Q.Y), &public_key[ATCA_ECCP256_SIG_SIZE / 2], ATCA_ECCP256_SIG_SIZE / 2); + ret = mbedtls_mpi_read_binary(&(ecp->Q.X), public_key, ATCA_ECCP256_SIG_SIZE / 2); } if (!ret) { - ret = mbedtls_mpi_read_binary(&(ecp->Q.Z), &temp, 1); + ret = mbedtls_mpi_read_binary(&(ecp->Q.Y), &public_key[ATCA_ECCP256_SIG_SIZE / 2], ATCA_ECCP256_SIG_SIZE / 2); } if (!ret) { + atca_mbedtls_eckey_t key_info = { device, slotid }; + /* This is a bit of a hack to force a context into the mbedtls keypair structure but it should work on any platform as it is in essence directly copying memory exactly as it appears in the structure */ - atca_mbedtls_eckey_t key_info = { device, slotid }; - ret = mbedtls_mpi_read_binary(&ecp->d, (const unsigned char*)&key_info, - sizeof(atca_mbedtls_eckey_t)); + +#ifndef MBEDTLS_ECDSA_VERIFY_ALT + if (0 == (ret = mbedtls_mpi_read_binary(&(ecp->Q.Z), &temp, 1))) + { + ret = mbedtls_mpi_read_binary(&ecp->d, (const unsigned char*)&key_info, sizeof(atca_mbedtls_eckey_t)); + } +#else + if (is_private) + { + if (0 == (ret = mbedtls_mpi_read_binary(&(ecp->Q.Z), &temp, 1))) + { + ret = mbedtls_mpi_read_binary(&ecp->d, (const unsigned char*)&key_info, sizeof(atca_mbedtls_eckey_t)); + } + } + else + { + ret = mbedtls_mpi_read_binary(&ecp->Q.Z, (const unsigned char*)&key_info, sizeof(atca_mbedtls_eckey_t)); + } +#endif } return ret; diff --git a/lib/mbedtls/atca_mbedtls_wrap.h b/lib/mbedtls/atca_mbedtls_wrap.h index 26adfea73..f63ac8e6f 100644 --- a/lib/mbedtls/atca_mbedtls_wrap.h +++ b/lib/mbedtls/atca_mbedtls_wrap.h @@ -43,6 +43,19 @@ struct mbedtls_pk_context; struct mbedtls_x509_crt; struct atcacert_def_s; +/** Structure to hold metadata - is written into the mbedtls pk structure as the private key + bignum value 'd' which otherwise would be unused. Bignums can be any arbitrary length of + bytes */ +typedef struct atca_mbedtls_eckey_s +{ + ATCADevice device; + uint16_t handle; +} atca_mbedtls_eckey_t; + +/* Integration Helper */ +int atca_mbedtls_ecdsa_sign(const mbedtls_mpi* d, mbedtls_mpi* r, mbedtls_mpi* s, + const unsigned char* buf, size_t buf_len); + /* Wrapper Functions */ int atca_mbedtls_pk_init_ext(ATCADevice device, struct mbedtls_pk_context * pkey, const uint16_t slotid); int atca_mbedtls_pk_init(struct mbedtls_pk_context * pkey, const uint16_t slotid); diff --git a/lib/pkcs11/pkcs11_cert.c b/lib/pkcs11/pkcs11_cert.c index cb9329e9f..e41267513 100644 --- a/lib/pkcs11/pkcs11_cert.c +++ b/lib/pkcs11/pkcs11_cert.c @@ -66,8 +66,10 @@ static void pkcs11_cert_check_trust_data(pkcs11_object_ptr pObject) #endif } -static CK_RV pkcs11_cert_load(pkcs11_object_ptr pObject, CK_ATTRIBUTE_PTR pAttribute) + +static CK_RV pkcs11_cert_load_ca(pkcs11_object_ptr pObject, CK_ATTRIBUTE_PTR pAttribute) { +#if ATCA_CA_SUPPORT ATCA_STATUS status = ATCA_SUCCESS; if (pObject->data) @@ -78,7 +80,7 @@ static CK_RV pkcs11_cert_load(pkcs11_object_ptr pObject, CK_ATTRIBUTE_PTR pAttri if (pAttribute->pValue && pAttribute->ulValueLen) { uint8_t ca_key[64]; - status = ATCA_SUCCESS; + status = ATCA_SUCCESS; if (cert_cfg->ca_cert_def) { @@ -125,39 +127,60 @@ static CK_RV pkcs11_cert_load(pkcs11_object_ptr pObject, CK_ATTRIBUTE_PTR pAttri } else { - if (atcab_is_ca_device(atcab_get_device_type())) + return pkcs11_attrib_empty(NULL, pAttribute); + } +#else + return CKR_GENERAL_ERROR; +#endif +} + + +static CK_RV pkcs11_cert_load_ta(pkcs11_object_ptr pObject, CK_ATTRIBUTE_PTR pAttribute) +{ +#if ATCA_TA_SUPPORT + uint8_t handle_info[TA_HANDLE_INFO_SIZE]; + ATCA_STATUS status = talib_info_get_handle_info(atcab_get_device(), pObject->slot, handle_info); + + if (ATCA_SUCCESS == status) + { + uint16_t cert_size = ((ta_element_attributes_t*)handle_info)->property; + + if (pAttribute->pValue && (pAttribute->ulValueLen >= cert_size)) { - return pkcs11_attrib_empty(NULL, pAttribute); + status = talib_read_element(atcab_get_device(), pObject->slot, &cert_size, pAttribute->pValue); + pAttribute->ulValueLen = cert_size; } else { -#if ATCA_TA_SUPPORT - uint8_t handle_info[TA_HANDLE_INFO_SIZE]; - status = talib_info_get_handle_info(atcab_get_device(), pObject->slot, handle_info); + pAttribute->ulValueLen = (CK_ULONG)cert_size; + } + } + else + { + return CKR_GENERAL_ERROR; + } + return CKR_OK; +#else + return CKR_GENERAL_ERROR; +#endif +} - if (ATCA_SUCCESS == status) - { - uint16_t cert_size = ((ta_element_attributes_t*)handle_info)->property; - if (pAttribute->pValue && (pAttribute->ulValueLen >= cert_size)) - { - status = talib_read_element(atcab_get_device(), pObject->slot, &cert_size, pAttribute->pValue); - pAttribute->ulValueLen = cert_size; - } - else - { - pAttribute->ulValueLen = (CK_ULONG)cert_size; - } - } - else - { - return CKR_GENERAL_ERROR; - } - return CKR_OK; -#endif - } +static CK_RV pkcs11_cert_load(pkcs11_object_ptr pObject, CK_ATTRIBUTE_PTR pAttribute) +{ + CK_RV ret = CKR_GENERAL_ERROR; + ATCADeviceType dev_type = atcab_get_device_type(); + + if (atcab_is_ca_device(dev_type)) + { + ret = pkcs11_cert_load_ca(pObject, pAttribute); } - return CKR_ARGUMENTS_BAD; + else if (atcab_is_ta_device(dev_type)) + { + ret = pkcs11_cert_load_ta(pObject, pAttribute); + } + + return ret; } CK_RV pkcs11_cert_get_encoded(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute) @@ -173,46 +196,58 @@ CK_RV pkcs11_cert_get_encoded(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute) return CKR_ARGUMENTS_BAD; } -CK_RV pkcs11_cert_get_type(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute) +static CK_RV pkcs11_cert_get_type_ca(pkcs11_object_ptr pObject, CK_ATTRIBUTE_PTR pAttribute) { - pkcs11_object_ptr obj_ptr = (pkcs11_object_ptr)pObject; - - if (obj_ptr) +#if ATCA_CA_SUPPORT + CK_RV rv = CKR_ARGUMENTS_BAD; + if (pObject) { - if (atcab_is_ca_device(atcab_get_device_type())) + pkcs11_cert_check_trust_data(pObject); + + if (pObject->data) { - pkcs11_cert_check_trust_data(obj_ptr); + atcacert_def_t* cert_cfg = (atcacert_def_t*)pObject->data; - if (obj_ptr->data) + if (CERTTYPE_X509 == cert_cfg->type) { - atcacert_def_t * cert_cfg = (atcacert_def_t*)obj_ptr->data; - - if (CERTTYPE_X509 == cert_cfg->type) - { - return pkcs11_attrib_value(pAttribute, CKC_X_509, sizeof(CK_CERTIFICATE_TYPE)); - } - else - { - return pkcs11_attrib_value(pAttribute, CKC_VENDOR_DEFINED, sizeof(CK_CERTIFICATE_TYPE)); - } + return pkcs11_attrib_value(pAttribute, CKC_X_509, sizeof(CK_CERTIFICATE_TYPE)); } else { - return pkcs11_attrib_empty(NULL, pAttribute); + return pkcs11_attrib_value(pAttribute, CKC_VENDOR_DEFINED, sizeof(CK_CERTIFICATE_TYPE)); } } else { - return pkcs11_attrib_value(pAttribute, CKC_X_509, sizeof(CK_CERTIFICATE_TYPE)); + rv = pkcs11_attrib_empty(NULL, pAttribute); } } - return CKR_ARGUMENTS_BAD; + return rv; +#else + return CKR_GENERAL_ERROR; +#endif +} + +CK_RV pkcs11_cert_get_type(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute) +{ + CK_RV rv; + + if (atcab_is_ca_device(atcab_get_device_type())) + { + rv = pkcs11_cert_get_type_ca(pObject, pAttribute); + } + else + { + rv = pkcs11_attrib_value(pAttribute, CKC_X_509, sizeof(CK_CERTIFICATE_TYPE)); + } + + return rv; } CK_RV pkcs11_cert_get_subject(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute) { -#ifndef ATCA_NO_HEAP +#if !defined(ATCA_NO_HEAP) && ATCA_CA_SUPPORT pkcs11_object_ptr obj_ptr = (pkcs11_object_ptr)pObject; CK_RV rv = CKR_ARGUMENTS_BAD; @@ -273,6 +308,7 @@ CK_RV pkcs11_cert_get_subject(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute) CK_RV pkcs11_cert_get_subject_key_id(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute) { +#if ATCA_CA_SUPPORT pkcs11_object_ptr obj_ptr = (pkcs11_object_ptr)pObject; if (obj_ptr) @@ -308,21 +344,14 @@ CK_RV pkcs11_cert_get_subject_key_id(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttr } return CKR_ARGUMENTS_BAD; +#else + return pkcs11_attrib_empty(NULL, pAttribute); +#endif } CK_RV pkcs11_cert_get_authority_key_id(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute) { - pkcs11_object_ptr obj_ptr = (pkcs11_object_ptr)pObject; - - if (obj_ptr) - { - pkcs11_cert_check_trust_data(obj_ptr); - - if (obj_ptr->data) - { - } - } - return CKR_ARGUMENTS_BAD; + return pkcs11_attrib_empty(NULL, pAttribute); } CK_RV pkcs11_cert_get_trusted_flag(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute) @@ -348,62 +377,62 @@ CK_RV pkcs11_cert_get_trusted_flag(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttrib */ const pkcs11_attrib_model pkcs11_cert_x509public_attributes[] = { /** Object Class - CK_OBJECT_CLASS */ - { CKA_CLASS, pkcs11_object_get_class }, + { CKA_CLASS, pkcs11_object_get_class }, /** CK_TRUE if object is a token object; CK_FALSE if object is a session object. Default is CK_FALSE. */ - { CKA_TOKEN, pkcs11_attrib_true }, + { CKA_TOKEN, pkcs11_attrib_true }, /** CK_TRUE if object is a private object; CK_FALSE if object is a public object. */ - { CKA_PRIVATE, pkcs11_token_get_access_type }, + { CKA_PRIVATE, pkcs11_token_get_access_type }, /** CK_TRUE if object can be modified. Default is CK_TRUE. */ - { CKA_MODIFIABLE, pkcs11_token_get_writable }, + { CKA_MODIFIABLE, pkcs11_token_get_writable }, /** Description of the object(default empty). */ - { CKA_LABEL, pkcs11_object_get_name }, + { CKA_LABEL, pkcs11_object_get_name }, /** CK_TRUE if object can be copied using C_CopyObject.Defaults to CK_TRUE. */ - { CKA_COPYABLE, pkcs11_attrib_false }, + { CKA_COPYABLE, pkcs11_attrib_false }, /** CK_TRUE if the object can be destroyed using C_DestroyObject. Default is CK_TRUE. */ - { CKA_DESTROYABLE, pkcs11_object_get_destroyable }, + { CKA_DESTROYABLE, pkcs11_object_get_destroyable }, /** Type of certificate */ - { CKA_CERTIFICATE_TYPE, pkcs11_cert_get_type }, + { CKA_CERTIFICATE_TYPE, pkcs11_cert_get_type }, /** The certificate can be trusted for the application that it was created. */ - { CKA_TRUSTED, pkcs11_cert_get_trusted_flag }, + { CKA_TRUSTED, pkcs11_cert_get_trusted_flag }, /** Default CK_CERTIFICATE_CATEGORY_UNSPECIFIED) */ - { CKA_CERTIFICATE_CATEGORY, pkcs11_object_get_type }, + { CKA_CERTIFICATE_CATEGORY, pkcs11_object_get_type }, /** Checksum */ - { CKA_CHECK_VALUE, NULL_PTR }, + { CKA_CHECK_VALUE, NULL_PTR }, /** Start date for the certificate (default empty) */ - { CKA_START_DATE, pkcs11_attrib_empty }, + { CKA_START_DATE, pkcs11_attrib_empty }, /** End date for the certificate (default empty) */ - { CKA_END_DATE, pkcs11_attrib_empty }, + { CKA_END_DATE, pkcs11_attrib_empty }, /** ALL: DER-encoding of the SubjectPublicKeyInfo for the public key contained in this certificate (default empty) SubjectPublicKeyInfo ::= SEQUENCE { algorithm AlgorithmIdentifier, subjectPublicKey BIT_STRING } */ - { CKA_PUBLIC_KEY_INFO, pkcs11_attrib_empty }, + { CKA_PUBLIC_KEY_INFO, pkcs11_attrib_empty }, /** DER-encoded Certificate subject name */ - { CKA_SUBJECT, pkcs11_cert_get_subject }, + { CKA_SUBJECT, pkcs11_cert_get_subject }, /** Key identifier for public/private key pair (default empty) */ - { CKA_ID, pkcs11_attrib_empty }, + { CKA_ID, pkcs11_attrib_empty }, /** DER-encoded Certificate issuer name (default empty)*/ - { CKA_ISSUER, pkcs11_attrib_empty }, + { CKA_ISSUER, pkcs11_attrib_empty }, /** DER-encoding of the certificate serial number (default empty) */ - { CKA_SERIAL_NUMBER, pkcs11_attrib_empty }, + { CKA_SERIAL_NUMBER, pkcs11_attrib_empty }, /** BER-encoded Complete Certificate */ - { CKA_VALUE, pkcs11_cert_get_encoded }, + { CKA_VALUE, pkcs11_cert_get_encoded }, /** If not empty this attribute gives the URL where the complete certificate can be obtained (default empty) */ - { CKA_URL, pkcs11_attrib_empty }, + { CKA_URL, pkcs11_attrib_empty }, /** Hash of the subject public key (default empty). Hash algorithm is defined by CKA_NAME_HASH_ALGORITHM */ - { CKA_HASH_OF_SUBJECT_PUBLIC_KEY, pkcs11_cert_get_subject_key_id }, + { CKA_HASH_OF_SUBJECT_PUBLIC_KEY, pkcs11_cert_get_subject_key_id }, /** Hash of the issuer public key (default empty). Hash algorithm is defined by CKA_NAME_HASH_ALGORITHM */ - { CKA_HASH_OF_ISSUER_PUBLIC_KEY, pkcs11_cert_get_authority_key_id }, + { CKA_HASH_OF_ISSUER_PUBLIC_KEY, pkcs11_cert_get_authority_key_id }, /** Java MIDP security domain. (default CK_SECURITY_DOMAIN_UNSPECIFIED) */ - { CKA_JAVA_MIDP_SECURITY_DOMAIN, NULL_PTR }, + { CKA_JAVA_MIDP_SECURITY_DOMAIN, NULL_PTR }, /** Defines the mechanism used to calculate CKA_HASH_OF_SUBJECT_PUBLIC_KEY and CKA_HASH_OF_ISSUER_PUBLIC_KEY. If the attribute is not present then the type defaults to SHA-1. */ - { CKA_NAME_HASH_ALGORITHM, pkcs11_attrib_empty }, + { CKA_NAME_HASH_ALGORITHM, pkcs11_attrib_empty }, }; const CK_ULONG pkcs11_cert_x509public_attributes_count = PKCS11_UTIL_ARRAY_SIZE(pkcs11_cert_x509public_attributes); @@ -413,56 +442,56 @@ const CK_ULONG pkcs11_cert_x509public_attributes_count = PKCS11_UTIL_ARRAY_SIZE( */ const pkcs11_attrib_model pkcs11_cert_wtlspublic_attributes[] = { /** Object Class - CK_OBJECT_CLASS */ - { CKA_CLASS, pkcs11_object_get_class }, + { CKA_CLASS, pkcs11_object_get_class }, /** CK_TRUE if object is a token object; CK_FALSE if object is a session object. Default is CK_FALSE. */ - { CKA_TOKEN, pkcs11_attrib_true }, + { CKA_TOKEN, pkcs11_attrib_true }, /** CK_TRUE if object is a private object; CK_FALSE if object is a public object. */ - { CKA_PRIVATE, pkcs11_token_get_access_type }, + { CKA_PRIVATE, pkcs11_token_get_access_type }, /** CK_TRUE if object can be modified. Default is CK_TRUE. */ - { CKA_MODIFIABLE, NULL_PTR }, + { CKA_MODIFIABLE, NULL_PTR }, /** Description of the object(default empty). */ - { CKA_LABEL, pkcs11_object_get_name }, + { CKA_LABEL, pkcs11_object_get_name }, /** CK_TRUE if object can be copied using C_CopyObject.Defaults to CK_TRUE. */ - { CKA_COPYABLE, pkcs11_attrib_false }, + { CKA_COPYABLE, pkcs11_attrib_false }, /** CK_TRUE if the object can be destroyed using C_DestroyObject. Default is CK_TRUE. */ - { CKA_DESTROYABLE, pkcs11_object_get_destroyable }, + { CKA_DESTROYABLE, pkcs11_object_get_destroyable }, /** Type of certificate */ - { CKA_CERTIFICATE_TYPE, pkcs11_cert_get_type }, + { CKA_CERTIFICATE_TYPE, pkcs11_cert_get_type }, /** The certificate can be trusted for the application that it was created. */ - { CKA_TRUSTED, NULL_PTR }, + { CKA_TRUSTED, NULL_PTR }, /** Default CK_CERTIFICATE_CATEGORY_UNSPECIFIED) */ - { CKA_CERTIFICATE_CATEGORY, pkcs11_object_get_type }, + { CKA_CERTIFICATE_CATEGORY, pkcs11_object_get_type }, /** Checksum */ - { CKA_CHECK_VALUE, NULL_PTR }, + { CKA_CHECK_VALUE, NULL_PTR }, /** Start date for the certificate (default empty) */ - { CKA_START_DATE, pkcs11_attrib_empty }, + { CKA_START_DATE, pkcs11_attrib_empty }, /** End date for the certificate (default empty) */ - { CKA_END_DATE, pkcs11_attrib_empty }, + { CKA_END_DATE, pkcs11_attrib_empty }, /** ALL: DER-encoding of the SubjectPublicKeyInfo for the public key contained in this certificate (default empty) SubjectPublicKeyInfo ::= SEQUENCE { algorithm AlgorithmIdentifier, subjectPublicKey BIT_STRING } */ - { CKA_PUBLIC_KEY_INFO, pkcs11_attrib_empty }, + { CKA_PUBLIC_KEY_INFO, pkcs11_attrib_empty }, /** WTLS-encoded Certificate subject name */ - { CKA_SUBJECT, pkcs11_attrib_empty }, + { CKA_SUBJECT, pkcs11_attrib_empty }, /** WTLS-encoded Certificate issuer name (default empty)*/ - { CKA_ISSUER, pkcs11_attrib_empty }, + { CKA_ISSUER, pkcs11_attrib_empty }, /** WTLS-encoded Complete Certificate */ - { CKA_VALUE, pkcs11_cert_get_encoded }, + { CKA_VALUE, pkcs11_cert_get_encoded }, /** If not empty this attribute gives the URL where the complete certificate can be obtained (default empty) */ - { CKA_URL, pkcs11_attrib_empty }, + { CKA_URL, pkcs11_attrib_empty }, /** Hash of the subject public key (default empty). Hash algorithm is defined by CKA_NAME_HASH_ALGORITHM */ - { CKA_HASH_OF_SUBJECT_PUBLIC_KEY, pkcs11_cert_get_subject_key_id }, + { CKA_HASH_OF_SUBJECT_PUBLIC_KEY, pkcs11_cert_get_subject_key_id }, /** Hash of the issuer public key (default empty). Hash algorithm is defined by CKA_NAME_HASH_ALGORITHM */ - { CKA_HASH_OF_ISSUER_PUBLIC_KEY, pkcs11_attrib_empty }, + { CKA_HASH_OF_ISSUER_PUBLIC_KEY, pkcs11_attrib_empty }, /** Defines the mechanism used to calculate CKA_HASH_OF_SUBJECT_PUBLIC_KEY and CKA_HASH_OF_ISSUER_PUBLIC_KEY. If the attribute is not present then the type defaults to SHA-1. */ - { CKA_NAME_HASH_ALGORITHM, pkcs11_attrib_empty }, + { CKA_NAME_HASH_ALGORITHM, pkcs11_attrib_empty }, }; const CK_ULONG pkcs11_cert_wtlspublic_attributes_count = PKCS11_UTIL_ARRAY_SIZE(pkcs11_cert_wtlspublic_attributes); @@ -472,56 +501,56 @@ const CK_ULONG pkcs11_cert_wtlspublic_attributes_count = PKCS11_UTIL_ARRAY_SIZE( */ const pkcs11_attrib_model pkcs11_cert_x509_attributes[] = { /** Object Class - CK_OBJECT_CLASS */ - { CKA_CLASS, pkcs11_object_get_class }, + { CKA_CLASS, pkcs11_object_get_class }, /** CK_TRUE if object is a token object; CK_FALSE if object is a session object. Default is CK_FALSE. */ - { CKA_TOKEN, pkcs11_attrib_true }, + { CKA_TOKEN, pkcs11_attrib_true }, /** CK_TRUE if object is a private object; CK_FALSE if object is a public object. */ - { CKA_PRIVATE, pkcs11_token_get_access_type }, + { CKA_PRIVATE, pkcs11_token_get_access_type }, /** CK_TRUE if object can be modified. Default is CK_TRUE. */ - { CKA_MODIFIABLE, NULL_PTR }, + { CKA_MODIFIABLE, NULL_PTR }, /** Description of the object(default empty). */ - { CKA_LABEL, pkcs11_object_get_name }, + { CKA_LABEL, pkcs11_object_get_name }, /** CK_TRUE if object can be copied using C_CopyObject.Defaults to CK_TRUE. */ - { CKA_COPYABLE, pkcs11_attrib_false }, + { CKA_COPYABLE, pkcs11_attrib_false }, /** CK_TRUE if the object can be destroyed using C_DestroyObject. Default is CK_TRUE. */ - { CKA_DESTROYABLE, pkcs11_object_get_destroyable }, + { CKA_DESTROYABLE, pkcs11_object_get_destroyable }, /** Type of certificate */ - { CKA_CERTIFICATE_TYPE, pkcs11_cert_get_type }, + { CKA_CERTIFICATE_TYPE, pkcs11_cert_get_type }, /** The certificate can be trusted for the application that it was created. */ - { CKA_TRUSTED, NULL_PTR }, + { CKA_TRUSTED, NULL_PTR }, /** Default CK_CERTIFICATE_CATEGORY_UNSPECIFIED) */ - { CKA_CERTIFICATE_CATEGORY, pkcs11_object_get_type }, + { CKA_CERTIFICATE_CATEGORY, pkcs11_object_get_type }, /** Checksum */ - { CKA_CHECK_VALUE, NULL_PTR }, + { CKA_CHECK_VALUE, NULL_PTR }, /** Start date for the certificate (default empty) */ - { CKA_START_DATE, pkcs11_attrib_empty }, + { CKA_START_DATE, pkcs11_attrib_empty }, /** End date for the certificate (default empty) */ - { CKA_END_DATE, pkcs11_attrib_empty }, + { CKA_END_DATE, pkcs11_attrib_empty }, /** ALL: DER-encoding of the SubjectPublicKeyInfo for the public key contained in this certificate (default empty) SubjectPublicKeyInfo ::= SEQUENCE { algorithm AlgorithmIdentifier, subjectPublicKey BIT_STRING } */ - { CKA_PUBLIC_KEY_INFO, pkcs11_attrib_empty }, + { CKA_PUBLIC_KEY_INFO, pkcs11_attrib_empty }, /** X509: DER-encoding of the attribute certificate's subject field. This is distinct from the CKA_SUBJECT attribute contained in CKC_X_509 certificates because the ASN.1 syntax and encoding are different. */ - { CKA_OWNER, pkcs11_attrib_empty }, + { CKA_OWNER, pkcs11_attrib_empty }, /** X509: DER-encoding of the attribute certificate's issuer field. This is distinct from the CKA_ISSUER attribute contained in CKC_X_509 certificates because the ASN.1 syntax and encoding are different. (default empty) */ - { CKA_AC_ISSUER, pkcs11_attrib_empty }, + { CKA_AC_ISSUER, pkcs11_attrib_empty }, /** DER-encoding of the certificate serial number (default empty) */ - { CKA_SERIAL_NUMBER, pkcs11_attrib_empty }, + { CKA_SERIAL_NUMBER, pkcs11_attrib_empty }, /** X509: BER-encoding of a sequence of object identifier values corresponding to the attribute types contained in the certificate. When present, this field offers an opportunity for applications to search for a particular attribute certificate without fetching and parsing the certificate itself. (default empty) */ - { CKA_ATTR_TYPES, pkcs11_attrib_empty }, + { CKA_ATTR_TYPES, pkcs11_attrib_empty }, /** BER-encoded Complete Certificate */ - { CKA_VALUE, pkcs11_cert_get_encoded }, + { CKA_VALUE, pkcs11_cert_get_encoded }, }; const CK_ULONG pkcs11_cert_x509_attributes_count = PKCS11_UTIL_ARRAY_SIZE(pkcs11_cert_x509_attributes); @@ -538,7 +567,11 @@ CK_RV pkcs11_cert_x509_write(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute) if (atcab_is_ca_device(atcab_get_device_type())) { +#if ATCA_CA_SUPPORT status = atcacert_write_cert(obj_ptr->data, pAttribute->pValue, pAttribute->ulValueLen); +#else + status = ATCA_NO_DEVICES; +#endif } else { diff --git a/lib/pkcs11/pkcs11_config.c b/lib/pkcs11/pkcs11_config.c index 4c91c456a..dab15b3d3 100644 --- a/lib/pkcs11/pkcs11_config.c +++ b/lib/pkcs11/pkcs11_config.c @@ -55,7 +55,9 @@ void pkcs11_config_init_private(pkcs11_object_ptr pObject, char * label, size_t pObject->class_type = CKK_EC; pObject->attributes = pkcs11_key_private_attributes; pObject->count = pkcs11_key_private_attributes_count; +#if ATCA_CA_SUPPORT pObject->data = NULL; +#endif pObject->size = 16; } @@ -71,10 +73,30 @@ void pkcs11_config_init_public(pkcs11_object_ptr pObject, char * label, size_t l pObject->class_type = CKK_EC; pObject->attributes = pkcs11_key_public_attributes; pObject->count = pkcs11_key_public_attributes_count; +#if ATCA_CA_SUPPORT pObject->data = NULL; +#endif pObject->size = 64; } +void pkcs11_config_init_secret(pkcs11_object_ptr pObject, char * label, size_t len, uint8_t keylen) +{ + if (len >= PKCS11_MAX_LABEL_SIZE) + { + len = PKCS11_MAX_LABEL_SIZE - 1; + } + memcpy(pObject->name, label, len); + pObject->name[len] = '\0'; + pObject->class_id = CKO_SECRET_KEY; + pObject->class_type = CKK_GENERIC_SECRET; + pObject->attributes = pkcs11_key_secret_attributes; + pObject->count = pkcs11_key_secret_attributes_count; +#if ATCA_CA_SUPPORT + pObject->data = NULL; +#endif + pObject->size = keylen; +} + void pkcs11_config_init_cert(pkcs11_object_ptr pObject, char * label, size_t len) { if (len >= PKCS11_MAX_LABEL_SIZE) @@ -87,7 +109,9 @@ void pkcs11_config_init_cert(pkcs11_object_ptr pObject, char * label, size_t len pObject->class_type = 0; pObject->attributes = pkcs11_cert_x509public_attributes; pObject->count = pkcs11_cert_x509public_attributes_count; +#if ATCA_CA_SUPPORT pObject->data = NULL; +#endif pObject->size = 0; } @@ -412,7 +436,9 @@ static CK_RV pkcs11_config_parse_object(pkcs11_slot_ctx_ptr slot_ctx, char* cfgs pkcs11_config_init_private(pObject, argv[1], strlen(argv[1])); pObject->slot = slot; pObject->flags = 0; +#if ATCA_CA_SUPPORT pObject->config = &slot_ctx->cfg_zone; +#endif } /* Every private key object needs a cooresponding public key object */ @@ -425,7 +451,9 @@ static CK_RV pkcs11_config_parse_object(pkcs11_slot_ctx_ptr slot_ctx, char* cfgs pkcs11_config_init_public(pPubkey, argv[1], strlen(argv[1])); pPubkey->slot = slot; pPubkey->flags = 0; +#if ATCA_CA_SUPPORT pPubkey->config = &slot_ctx->cfg_zone; +#endif } else { @@ -440,7 +468,27 @@ static CK_RV pkcs11_config_parse_object(pkcs11_slot_ctx_ptr slot_ctx, char* cfgs pkcs11_config_init_public(pObject, argv[1], strlen(argv[1])); pObject->slot = (uint16_t)strtol(argv[2], NULL, 16); pObject->flags = 0; +#if ATCA_CA_SUPPORT pObject->config = &slot_ctx->cfg_zone; +#endif + } + } + else if (!strcmp(argv[0], "secret") && argc >= 3) + { + rv = pkcs11_object_alloc(&pObject); + if (!rv && pObject) + { + uint8_t keylen = 32; + if (4 == argc) + { + keylen = (uint8_t)strtol(argv[3], NULL, 10); + } + pkcs11_config_init_secret(pObject, argv[1], strlen(argv[1]), keylen); + pObject->slot = (uint16_t)strtol(argv[2], NULL, 16); + pObject->flags = 0; +#if ATCA_CA_SUPPORT + pObject->config = &slot_ctx->cfg_zone; +#endif } } else if (!strcmp(argv[0], "certificate") && argc >= 3) @@ -460,7 +508,9 @@ static CK_RV pkcs11_config_parse_object(pkcs11_slot_ctx_ptr slot_ctx, char* cfgs // pObject->size = g_cert_def_2_device.cert_template_size; // pObject->data = &g_cert_def_2_device; pObject->flags = 0; +#if ATCA_CA_SUPPORT pObject->config = &slot_ctx->cfg_zone; +#endif } } else @@ -484,7 +534,7 @@ static CK_RV pkcs11_config_parse_handle(uint16_t * handle, char* cfgstr) if (argc == 1) { - *handle = (uint16_t)strtol(argv[2], NULL, 16); + *handle = (uint16_t)strtol(argv[0], NULL, 16); rv = CKR_OK; } @@ -517,6 +567,7 @@ static CK_RV pkcs11_config_parse_slot_file(pkcs11_slot_ctx_ptr slot_ctx, int arg { rv = pkcs11_config_parse_freeslots(slot_ctx, argv[i + 1]); } +#if ATCA_TA_SUPPORT else if (!strcmp(argv[i], "user_pin_handle")) { rv = pkcs11_config_parse_handle(&slot_ctx->user_pin_handle, argv[i + 1]); @@ -525,6 +576,7 @@ static CK_RV pkcs11_config_parse_slot_file(pkcs11_slot_ctx_ptr slot_ctx, int arg { rv = pkcs11_config_parse_handle(&slot_ctx->so_pin_handle, argv[i + 1]); } +#endif else if (!strcmp(argv[i], "object")) { rv = pkcs11_config_parse_object(slot_ctx, argv[i + 1]); @@ -545,30 +597,36 @@ static CK_RV pkcs11_config_parse_object_file(pkcs11_slot_ctx_ptr slot_ctx, CK_BY { pObject->slot = slot; pObject->flags = PKCS11_OBJECT_FLAG_DESTROYABLE; +#if ATCA_CA_SUPPORT pObject->config = &slot_ctx->cfg_zone; +#endif memset(pObject->name, 0, sizeof(pObject->name)); - } - for (i = 0; i < argc; i += 2) - { - if (!strcmp(argv[i], "type")) + for (i = 0; i < argc; i += 2) { - if (!strcmp(argv[i + 1], "private")) + if (!strcmp(argv[i], "type")) { - privkey = TRUE; - pkcs11_config_init_private(pObject, "", 0); + if (!strcmp(argv[i + 1], "private")) + { + privkey = TRUE; + pkcs11_config_init_private(pObject, "", 0); + } + else if (!strcmp(argv[i + 1], "public")) + { + pkcs11_config_init_public(pObject, "", 0); + } + else if (!strcmp(argv[i + 1], "secret")) + { + pkcs11_config_init_secret(pObject, "", 0, 32); + } + //if (!strcmp(argv[i + 1], "certificate")) + //{ + //} } - else if (!strcmp(argv[i + 1], "public")) + else if (!strcmp(argv[i], "label")) { - pkcs11_config_init_public(pObject, "", 0); + strncpy(pObject->name, argv[i + 1], sizeof(pObject->name)); } - //if (!strcmp(argv[i + 1], "certificate")) - //{ - //} - } - else if (!strcmp(argv[i], "label")) - { - strncpy(pObject->name, argv[i + 1], sizeof(pObject->name)); } } @@ -581,7 +639,9 @@ static CK_RV pkcs11_config_parse_object_file(pkcs11_slot_ctx_ptr slot_ctx, CK_BY { pPubkey->slot = slot; pPubkey->flags = pObject->flags; +#if ATCA_CA_SUPPORT pPubkey->config = &slot_ctx->cfg_zone; +#endif pkcs11_config_init_public(pPubkey, pObject->name, strlen(pObject->name)); } else @@ -604,11 +664,11 @@ CK_RV pkcs11_config_key(pkcs11_lib_ctx_ptr pLibCtx, pkcs11_slot_ctx_ptr pSlot, p FILE* fp; char *objtype = ""; char filename[200]; - int i; + int i = 0; CK_RV rv = CKR_FUNCTION_FAILED; +#if ATCA_CA_SUPPORT /* Find a free slot that matches the object type */ - for (i = 0; i < 16; i++) { if (pSlot->flags & (1 << i)) @@ -638,8 +698,21 @@ CK_RV pkcs11_config_key(pkcs11_lib_ctx_ptr pLibCtx, pkcs11_slot_ctx_ptr pSlot, p break; } } + else if (CKO_SECRET_KEY == pObject->class_id) + { + if ((6 == keytype) || (7 == keytype)) + { + pObject->slot = i; + pObject->flags = PKCS11_OBJECT_FLAG_DESTROYABLE; + pObject->config = &pSlot->cfg_zone; + pkcs11_config_init_secret(pObject, pLabel->pValue, pLabel->ulValueLen, 32); + objtype = "secret"; + break; + } + } } } +#endif if (i < 16) { diff --git a/lib/pkcs11/pkcs11_config.h.in b/lib/pkcs11/pkcs11_config.h.in index 617ed3328..62cad8fc6 100644 --- a/lib/pkcs11/pkcs11_config.h.in +++ b/lib/pkcs11/pkcs11_config.h.in @@ -75,6 +75,17 @@ #define PKCS11_MAX_LABEL_SIZE 30 #endif +/** Define to always convert PIN using KDF */ +#cmakedefine PKCS11_PIN_KDF_ALWAYS + +/** Define to use PBKDF2 for PIN KDF */ +#cmakedefine PKCS11_PIN_PBKDF2_EN + +/** Define how many iterations PBKDF2 will use for PIN KDF */ +#if defined(PKCS11_PIN_PBKDF2_EN) && !defined(PKCS11_PIN_PBKDF2_ITERATIONS) +#define PKCS11_PIN_PBKDF2_ITERATIONS 2 +#endif + /****************************************************************************/ /* The following configuration options are for fine tuning of the library */ /****************************************************************************/ diff --git a/lib/pkcs11/pkcs11_encrypt.c b/lib/pkcs11/pkcs11_encrypt.c new file mode 100644 index 000000000..bb70a97a4 --- /dev/null +++ b/lib/pkcs11/pkcs11_encrypt.c @@ -0,0 +1,607 @@ +/** + * \file + * \brief PKCS11 Library Encrypt Support + * + * \copyright (c) 2015-2020 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include "cryptoauthlib.h" + +#include "pkcs11_config.h" +#include "pkcs11_encrypt.h" +#include "pkcs11_debug.h" +#include "pkcs11_init.h" +#include "pkcs11_object.h" +#include "pkcs11_session.h" +#include "pkcs11_util.h" + + +/** + * \defgroup pkcs11 Encrypt (pkcs11_encrypt_) + @{ */ + +CK_RV pkcs11_encrypt_init(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hObject) +{ + pkcs11_session_ctx_ptr pSession; + pkcs11_object_ptr pObject; + CK_RV rv; + + rv = pkcs11_init_check(NULL_PTR, FALSE); + if (rv) + { + return rv; + } + + if (!pMechanism) + { + return CKR_ARGUMENTS_BAD; + } + + rv = pkcs11_session_check(&pSession, hSession); + if (rv) + { + return rv; + } + + rv = pkcs11_object_check(&pObject, hObject); + if (rv) + { + return rv; + } + + if (CKM_VENDOR_DEFINED == pSession->active_mech) + { + switch (pMechanism->mechanism) + { + case CKM_AES_ECB: + rv = CKR_OK; + break; + case CKM_AES_GCM: + if (pMechanism->pParameter && sizeof(CK_GCM_PARAMS) == pMechanism->ulParameterLen) + { + CK_GCM_PARAMS_PTR pParams = (CK_GCM_PARAMS_PTR)pMechanism->pParameter; + + if (pParams->ulTagBits % 8 == 0) + { + pSession->active_mech_data.gcm.tag_len = pParams->ulTagBits / 8; + if (CKR_OK == (rv = pkcs11_util_convert_rv(atcab_aes_gcm_init(&pSession->active_mech_data.gcm.context, + pObject->slot, 0, pParams->pIv, pParams->ulIvLen)))) + { + rv = pkcs11_util_convert_rv(atcab_aes_gcm_aad_update(&pSession->active_mech_data.gcm.context, pParams->pAAD, pParams->ulAADLen)); + } + } + else + { + rv = CKR_ARGUMENTS_BAD; + } + } + else + { + rv = CKR_ARGUMENTS_BAD; + } + + break; + default: + rv = CKR_MECHANISM_INVALID; + break; + } + } + else + { + rv = CKR_OPERATION_ACTIVE; + } + + if (CKR_OK == rv) + { + pSession->active_object = hObject; + pSession->active_mech = pMechanism->mechanism; + } + + return rv; +} + +CK_RV pkcs11_encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, + CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen) +{ + pkcs11_lib_ctx_ptr pLibCtx = NULL; + pkcs11_session_ctx_ptr pSession; + pkcs11_object_ptr pKey; + CK_RV rv; + ATCA_STATUS status = ATCA_SUCCESS; + + rv = pkcs11_init_check(&pLibCtx, FALSE); + if (rv) + { + return rv; + } + + if (!pData || !ulDataLen || !pEncryptedData || !pulEncryptedDataLen) + { + return CKR_ARGUMENTS_BAD; + } + + rv = pkcs11_session_check(&pSession, hSession); + if (rv) + { + return rv; + } + + rv = pkcs11_object_check(&pKey, pSession->active_object); + if (rv) + { + return rv; + } + + switch (pSession->active_mech) + { + case CKM_AES_ECB: + if (ulDataLen == ATCA_AES128_BLOCK_SIZE && *pulEncryptedDataLen > ATCA_AES128_BLOCK_SIZE) + { + status = atcab_aes_encrypt(pKey->slot, 0, pData, pEncryptedData); + *pulEncryptedDataLen = ATCA_AES128_BLOCK_SIZE; + } + else + { + rv = CKR_ARGUMENTS_BAD; + } + break; + case CKM_AES_GCM: + if (ATCA_SUCCESS == (status = atcab_aes_gcm_encrypt_update(&pSession->active_mech_data.gcm.context, pData, ulDataLen, pEncryptedData))) + { + status = atcab_aes_gcm_encrypt_finish(&pSession->active_mech_data.gcm.context, &pEncryptedData[ulDataLen], + pSession->active_mech_data.gcm.tag_len); + *pulEncryptedDataLen = ulDataLen + pSession->active_mech_data.gcm.tag_len; + } + break; + default: + rv = CKR_MECHANISM_INVALID; + break; + } + pSession->active_mech = CKM_VENDOR_DEFINED; + + if (ATCA_SUCCESS != status && CKR_OK == rv) + { + rv = pkcs11_util_convert_rv(status); + } + + return rv; +} + +CK_RV pkcs11_encrypt_update +( + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pData, + CK_ULONG ulDataLen, + CK_BYTE_PTR pEncryptedData, + CK_ULONG_PTR pulEncryptedDataLen +) +{ + pkcs11_lib_ctx_ptr pLibCtx = NULL; + pkcs11_session_ctx_ptr pSession; + pkcs11_object_ptr pKey; + CK_RV rv; + ATCA_STATUS status = ATCA_SUCCESS; + + rv = pkcs11_init_check(&pLibCtx, FALSE); + if (rv) + { + return rv; + } + + if (!pData || !ulDataLen || !pEncryptedData || !pulEncryptedDataLen) + { + return CKR_ARGUMENTS_BAD; + } + + rv = pkcs11_session_check(&pSession, hSession); + if (rv) + { + return rv; + } + + rv = pkcs11_object_check(&pKey, pSession->active_object); + if (rv) + { + return rv; + } + + switch (pSession->active_mech) + { + case CKM_AES_ECB: + if (ulDataLen == ATCA_AES128_BLOCK_SIZE && *pulEncryptedDataLen > ATCA_AES128_BLOCK_SIZE) + { + status = atcab_aes_encrypt(pKey->slot, 0, pData, pEncryptedData); + *pulEncryptedDataLen = ATCA_AES128_BLOCK_SIZE; + } + else + { + rv = CKR_ARGUMENTS_BAD; + } + break; + case CKM_AES_GCM: + status = atcab_aes_gcm_encrypt_update(&pSession->active_mech_data.gcm.context, pData, ulDataLen, pEncryptedData); + break; + default: + rv = CKR_MECHANISM_INVALID; + break; + } + + if (ATCA_SUCCESS != status && CKR_OK == rv) + { + rv = pkcs11_util_convert_rv(status); + } + + return rv; +} + +/** + * \brief Finishes a multiple-part encryption operation + */ +CK_RV pkcs11_encrypt_final(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen) +{ + pkcs11_lib_ctx_ptr pLibCtx = NULL; + pkcs11_session_ctx_ptr pSession; + pkcs11_object_ptr pKey; + CK_RV rv; + ATCA_STATUS status = ATCA_SUCCESS; + + rv = pkcs11_init_check(&pLibCtx, FALSE); + if (rv) + { + return rv; + } + + if (!pEncryptedData || !pulEncryptedDataLen) + { + return CKR_ARGUMENTS_BAD; + } + + rv = pkcs11_session_check(&pSession, hSession); + if (rv) + { + return rv; + } + + rv = pkcs11_object_check(&pKey, pSession->active_object); + if (rv) + { + return rv; + } + + switch (pSession->active_mech) + { + case CKM_AES_ECB: + break; + case CKM_AES_GCM: + status = atcab_aes_gcm_encrypt_finish(&pSession->active_mech_data.gcm.context, pEncryptedData, + pSession->active_mech_data.gcm.tag_len); + *pulEncryptedDataLen = pSession->active_mech_data.gcm.tag_len; + break; + default: + rv = CKR_MECHANISM_INVALID; + break; + } + + if (ATCA_SUCCESS != status && CKR_OK == rv) + { + rv = pkcs11_util_convert_rv(status); + } + + pSession->active_mech = CKM_VENDOR_DEFINED; + + return rv; +} + +CK_RV pkcs11_decrypt_init(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hObject) +{ + pkcs11_session_ctx_ptr pSession; + pkcs11_object_ptr pObject; + CK_RV rv; + + rv = pkcs11_init_check(NULL_PTR, FALSE); + if (rv) + { + return rv; + } + + if (!pMechanism) + { + return CKR_ARGUMENTS_BAD; + } + + rv = pkcs11_session_check(&pSession, hSession); + if (rv) + { + return rv; + } + + rv = pkcs11_object_check(&pObject, hObject); + if (rv) + { + return rv; + } + + if (CKM_VENDOR_DEFINED == pSession->active_mech) + { + switch (pMechanism->mechanism) + { + case CKM_AES_ECB: + rv = CKR_OK; + break; + case CKM_AES_GCM: + if (pMechanism->pParameter && sizeof(CK_GCM_PARAMS) == pMechanism->ulParameterLen) + { + CK_GCM_PARAMS_PTR pParams = (CK_GCM_PARAMS_PTR)pMechanism->pParameter; + + if (pParams->ulTagBits % 8 == 0) + { + pSession->active_mech_data.gcm.tag_len = pParams->ulTagBits / 8; + if (CKR_OK == (rv = pkcs11_util_convert_rv(atcab_aes_gcm_init(&pSession->active_mech_data.gcm.context, + pObject->slot, 0, pParams->pIv, pParams->ulIvLen)))) + { + rv = pkcs11_util_convert_rv(atcab_aes_gcm_aad_update(&pSession->active_mech_data.gcm.context, pParams->pAAD, pParams->ulAADLen)); + } + } + else + { + rv = CKR_ARGUMENTS_BAD; + } + } + else + { + rv = CKR_ARGUMENTS_BAD; + } + + break; + default: + rv = CKR_MECHANISM_INVALID; + break; + } + } + else + { + rv = CKR_OPERATION_ACTIVE; + } + + if (CKR_OK == rv) + { + pSession->active_object = hObject; + pSession->active_mech = pMechanism->mechanism; + } + + return rv; +} + +CK_RV pkcs11_decrypt +( + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pEncryptedData, + CK_ULONG ulEncryptedDataLen, + CK_BYTE_PTR pData, + CK_ULONG_PTR pulDataLen +) +{ + pkcs11_lib_ctx_ptr pLibCtx = NULL; + pkcs11_session_ctx_ptr pSession; + pkcs11_object_ptr pKey; + CK_RV rv; + ATCA_STATUS status = ATCA_SUCCESS; + + rv = pkcs11_init_check(&pLibCtx, FALSE); + if (rv) + { + return rv; + } + + if (!pEncryptedData || !ulEncryptedDataLen || !pData || !pulDataLen) + { + return CKR_ARGUMENTS_BAD; + } + + rv = pkcs11_session_check(&pSession, hSession); + if (rv) + { + return rv; + } + + rv = pkcs11_object_check(&pKey, pSession->active_object); + if (rv) + { + return rv; + } + + switch (pSession->active_mech) + { + case CKM_AES_ECB: + if (ulEncryptedDataLen == ATCA_AES128_BLOCK_SIZE && *pulDataLen >= ATCA_AES128_BLOCK_SIZE) + { + status = atcab_aes_decrypt(pKey->slot, 0, pEncryptedData, pData); + *pulDataLen = ATCA_AES128_BLOCK_SIZE; + } + else + { + rv = CKR_ARGUMENTS_BAD; + } + break; + case CKM_AES_GCM: + *pulDataLen = ulEncryptedDataLen - pSession->active_mech_data.gcm.tag_len; + if (ATCA_SUCCESS == (status = atcab_aes_gcm_decrypt_update(&pSession->active_mech_data.gcm.context, pEncryptedData, + *pulDataLen, pData))) + { + bool is_verified = FALSE; + status = atcab_aes_gcm_decrypt_finish(&pSession->active_mech_data.gcm.context, &pEncryptedData[*pulDataLen], + pSession->active_mech_data.gcm.tag_len, &is_verified); + if (!is_verified) + { + rv = CKR_ENCRYPTED_DATA_INVALID; + } + } + break; + default: + rv = CKR_MECHANISM_INVALID; + break; + } + + pSession->active_mech = CKM_VENDOR_DEFINED; + + if (ATCA_SUCCESS != status && CKR_OK == rv) + { + rv = pkcs11_util_convert_rv(status); + } + + return rv; +} + +CK_RV pkcs11_decrypt_update +( + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pEncryptedData, + CK_ULONG ulEncryptedDataLen, + CK_BYTE_PTR pData, + CK_ULONG_PTR pulDataLen +) +{ + pkcs11_lib_ctx_ptr pLibCtx = NULL; + pkcs11_session_ctx_ptr pSession; + pkcs11_object_ptr pKey; + CK_RV rv; + ATCA_STATUS status = ATCA_SUCCESS; + + rv = pkcs11_init_check(&pLibCtx, FALSE); + if (rv) + { + return rv; + } + + if (!pEncryptedData || !ulEncryptedDataLen || !pData || !pulDataLen) + { + return CKR_ARGUMENTS_BAD; + } + + rv = pkcs11_session_check(&pSession, hSession); + if (rv) + { + return rv; + } + + rv = pkcs11_object_check(&pKey, pSession->active_object); + if (rv) + { + return rv; + } + + switch (pSession->active_mech) + { + case CKM_AES_ECB: + if (ulEncryptedDataLen == ATCA_AES128_BLOCK_SIZE && *pulDataLen > ATCA_AES128_BLOCK_SIZE) + { + status = atcab_aes_decrypt(pKey->slot, 0, pData, pEncryptedData); + *pulDataLen = ATCA_AES128_BLOCK_SIZE; + } + else + { + rv = CKR_ARGUMENTS_BAD; + } + break; + case CKM_AES_GCM: + status = atcab_aes_gcm_decrypt_update(&pSession->active_mech_data.gcm.context, pEncryptedData, + *pulDataLen, pData); + break; + default: + rv = CKR_MECHANISM_INVALID; + break; + } + + if (ATCA_SUCCESS != status && CKR_OK == rv) + { + rv = pkcs11_util_convert_rv(status); + } + + return rv; +} + +/** + * \brief Finishes a multiple-part decryption operation + */ +CK_RV pkcs11_decrypt_final(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen) +{ + pkcs11_lib_ctx_ptr pLibCtx = NULL; + pkcs11_session_ctx_ptr pSession; + pkcs11_object_ptr pKey; + CK_RV rv; + ATCA_STATUS status = ATCA_SUCCESS; + + rv = pkcs11_init_check(&pLibCtx, FALSE); + if (rv) + { + return rv; + } + + if (!pData || !pulDataLen) + { + return CKR_ARGUMENTS_BAD; + } + + rv = pkcs11_session_check(&pSession, hSession); + if (rv) + { + return rv; + } + + rv = pkcs11_object_check(&pKey, pSession->active_object); + if (rv) + { + return rv; + } + + switch (pSession->active_mech) + { + case CKM_AES_ECB: + break; + case CKM_AES_GCM: + { + bool is_verified = FALSE; + status = atcab_aes_gcm_decrypt_finish(&pSession->active_mech_data.gcm.context, pData, + pSession->active_mech_data.gcm.tag_len, &is_verified); + if (!is_verified) + { + rv = CKR_ENCRYPTED_DATA_INVALID; + } + } + break; + default: + rv = CKR_MECHANISM_INVALID; + break; + } + + pSession->active_mech = CKM_VENDOR_DEFINED; + + if (ATCA_SUCCESS != status && CKR_OK == rv) + { + rv = pkcs11_util_convert_rv(status); + } + + return rv; +} + +/** @} */ diff --git a/lib/pkcs11/pkcs11_encrypt.h b/lib/pkcs11/pkcs11_encrypt.h new file mode 100644 index 000000000..c6a377fdf --- /dev/null +++ b/lib/pkcs11/pkcs11_encrypt.h @@ -0,0 +1,62 @@ +/** + * \file + * \brief PKCS11 Library AES Support + * + * \copyright (c) 2015-2020 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#ifndef PKCS11_ENCRYPT_H_ +#define PKCS11_ENCRYPT_H_ + +#include "pkcs11.h" + +#ifdef __cplusplus +extern "C" { +#endif + +CK_RV pkcs11_encrypt_init(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hObject); +CK_RV pkcs11_encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, + CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen); + +CK_RV pkcs11_encrypt_update(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, + CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen); + +CK_RV pkcs11_encrypt_final(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen); + +CK_RV pkcs11_decrypt_init(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hObject); + +CK_RV pkcs11_decrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, + CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen); + +CK_RV pkcs11_decrypt_update(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, + CK_BYTE_PTR pData, CK_ULONG_PTR pDataLen); + +CK_RV pkcs11_decrypt_final(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG_PTR pDataLen); + + +#ifdef __cplusplus +} +#endif + + +#endif /* PKCS11_ENCRYPT_H_ */ diff --git a/lib/pkcs11/pkcs11_init.c b/lib/pkcs11/pkcs11_init.c index 4a6d1af98..8d216bf95 100644 --- a/lib/pkcs11/pkcs11_init.c +++ b/lib/pkcs11/pkcs11_init.c @@ -281,6 +281,13 @@ CK_RV pkcs11_deinit(CK_VOID_PTR pReserved) return CKR_CRYPTOKI_NOT_INITIALIZED; } +#if ATCA_TA_SUPPORT + if (atcab_is_ta_device(atcab_get_device_type())) + { + (void)talib_auth_terminate(atcab_get_device()); + } +#endif + /* Release the crypto device */ atcab_release(); diff --git a/lib/pkcs11/pkcs11_key.c b/lib/pkcs11/pkcs11_key.c index b910fbb63..397e8031b 100644 --- a/lib/pkcs11/pkcs11_key.c +++ b/lib/pkcs11/pkcs11_key.c @@ -48,6 +48,7 @@ static CK_RV pkcs11_key_get_derivekey_flag(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR if (obj_ptr) { +#if ATCA_CA_SUPPORT atecc508a_config_t * pConfig = (atecc508a_config_t*)obj_ptr->config; if (!pConfig) @@ -63,6 +64,7 @@ static CK_RV pkcs11_key_get_derivekey_flag(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR { return pkcs11_attrib_false(NULL, pAttribute); } +#endif } return CKR_ARGUMENTS_BAD; @@ -74,6 +76,7 @@ static CK_RV pkcs11_key_get_local_flag(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAt if (obj_ptr) { +#if ATCA_CA_SUPPORT atecc508a_config_t * pConfig = (atecc508a_config_t*)obj_ptr->config; if (!pConfig) @@ -89,6 +92,7 @@ static CK_RV pkcs11_key_get_local_flag(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAt { return pkcs11_attrib_false(NULL, pAttribute); } +#endif } return CKR_ARGUMENTS_BAD; @@ -114,12 +118,32 @@ static const CK_MECHANISM_TYPE pkcs11_key_508_private_mech[] = { CKM_ECDSA_SHA256 }; +static const CK_MECHANISM_TYPE pkcs11_key_508_secret_mech[] = { + CKM_SHA256_HMAC, +// CKM_SHA256_HMAC_GENERAL +}; + +static const CK_MECHANISM_TYPE pkcs11_key_608_secret_mech[] = { + CKM_SHA256_HMAC, +// CKM_SHA256_HMAC_GENERAL, + CKM_AES_ECB, + CKM_AES_CBC, +// CKM_AES_CTR, + CKM_AES_GCM, +// CKM_AES_CCM, +// CKM_AES_CMAC, +// CKM_AES_CMAC_GENERAL, +// CKM_AES_ECB_ENCRYPT_DATA, +// CKM_AES_CBC_ENCRYPT_DATA +}; + static CK_RV pkcs11_key_get_allowed_mechanisms(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute) { pkcs11_object_ptr obj_ptr = (pkcs11_object_ptr)pObject; if (obj_ptr) { +#if ATCA_CA_SUPPORT atecc508a_config_t * pConfig = (atecc508a_config_t*)obj_ptr->config; if (!pConfig) @@ -127,16 +151,25 @@ static CK_RV pkcs11_key_get_allowed_mechanisms(CK_VOID_PTR pObject, CK_ATTRIBUTE return CKR_GENERAL_ERROR; } - if (ATCA_KEY_CONFIG_PRIVATE_MASK & pConfig->KeyConfig[obj_ptr->slot]) + if (ATCA_KEY_CONFIG_KEY_TYPE(4) == (ATCA_KEY_CONFIG_KEY_TYPE_MASK & pConfig->KeyConfig[obj_ptr->slot])) { - return pkcs11_attrib_fill(pAttribute, (CK_VOID_PTR)pkcs11_key_508_private_mech, - sizeof(pkcs11_key_508_private_mech)); + if (ATCA_KEY_CONFIG_PRIVATE_MASK & pConfig->KeyConfig[obj_ptr->slot]) + { + return pkcs11_attrib_fill(pAttribute, (CK_VOID_PTR)pkcs11_key_508_private_mech, + sizeof(pkcs11_key_508_private_mech)); + } + else + { + return pkcs11_attrib_fill(pAttribute, (CK_VOID_PTR)pkcs11_key_508_public_mech, + sizeof(pkcs11_key_508_public_mech)); + } } else { - return pkcs11_attrib_fill(pAttribute, (CK_VOID_PTR)pkcs11_key_508_public_mech, - sizeof(pkcs11_key_508_public_mech)); + return pkcs11_attrib_fill(pAttribute, (CK_VOID_PTR)pkcs11_key_608_secret_mech, + sizeof(pkcs11_key_608_secret_mech)); } +#endif } return CKR_ARGUMENTS_BAD; @@ -161,41 +194,40 @@ static const uint8_t ec_x962_asn1_header[] = { static CK_RV pkcs11_key_get_public_key(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute) { pkcs11_object_ptr obj_ptr = (pkcs11_object_ptr)pObject; - atecc508a_config_t * pConfig; - CK_UTF8CHAR ec_asn1_key[sizeof(ec_pubkey_asn1_header) + ATCA_PUB_KEY_SIZE]; - ATCA_STATUS status; + CK_RV rv = CKR_ARGUMENTS_BAD; - if (!obj_ptr) + if (obj_ptr) { - return CKR_ARGUMENTS_BAD; - } + CK_BBOOL is_private = false; - pConfig = (atecc508a_config_t*)obj_ptr->config; + if (CKR_OK == (rv = pkcs11_object_is_private(obj_ptr, &is_private))) + { + CK_UTF8CHAR ec_asn1_key[sizeof(ec_pubkey_asn1_header) + ATCA_ECCP256_PUBKEY_SIZE]; + ATCA_STATUS status; - if (!pConfig) - { - return CKR_GENERAL_ERROR; - } + memcpy(ec_asn1_key, ec_pubkey_asn1_header, sizeof(ec_pubkey_asn1_header)); - memcpy(ec_asn1_key, ec_pubkey_asn1_header, sizeof(ec_pubkey_asn1_header)); + if (is_private) + { + status = atcab_get_pubkey(obj_ptr->slot, &ec_asn1_key[sizeof(ec_pubkey_asn1_header)]); + } + else + { + status = atcab_read_pubkey(obj_ptr->slot, &ec_asn1_key[sizeof(ec_pubkey_asn1_header)]); + } - if (ATCA_KEY_CONFIG_PRIVATE_MASK & pConfig->KeyConfig[obj_ptr->slot]) - { - status = atcab_get_pubkey(obj_ptr->slot, &ec_asn1_key[sizeof(ec_pubkey_asn1_header)]); - } - else - { - status = atcab_read_pubkey(obj_ptr->slot, &ec_asn1_key[sizeof(ec_pubkey_asn1_header)]); + if (ATCA_SUCCESS == status) + { + rv = pkcs11_attrib_fill(pAttribute, ec_asn1_key, sizeof(ec_asn1_key)); + } + else + { + rv = CKR_FUNCTION_FAILED; + } + } } - if (ATCA_SUCCESS == status) - { - return pkcs11_attrib_fill(pAttribute, ec_asn1_key, sizeof(ec_asn1_key)); - } - else - { - return CKR_FUNCTION_FAILED; - } + return rv; } static const uint8_t pkcs11_key_ec_params[] = { 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07 }; @@ -208,58 +240,43 @@ static CK_RV pkcs11_key_get_ec_params(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAtt static CK_RV pkcs11_key_get_ec_point(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute) { pkcs11_object_ptr obj_ptr = (pkcs11_object_ptr)pObject; - CK_UTF8CHAR ec_asn1_key[3 + ATCA_PUB_KEY_SIZE] = { 0x04, 0x41, 0x04 }; - ATCA_STATUS status = ATCA_SUCCESS; - + CK_RV rv = CKR_ARGUMENTS_BAD; - if (!obj_ptr) - { - return CKR_ARGUMENTS_BAD; - } - - if (pAttribute->pValue) + if (obj_ptr) { - bool is_private = TRUE; - - if (obj_ptr->flags & PKCS11_OBJECT_FLAG_TA_TYPE) - { -#if ATCA_TA_SUPPORT - is_private = (TA_CLASS_PRIVATE_KEY == obj_ptr->handle_info.element_CKA & 0xF); -#endif - } - else + if (pAttribute->pValue) { - atecc508a_config_t * pConfig = (atecc508a_config_t*)obj_ptr->config; + CK_BBOOL is_private; - if (!pConfig) + if (CKR_OK == (rv = pkcs11_object_is_private(obj_ptr, &is_private))) { - return CKR_GENERAL_ERROR; - } + CK_UTF8CHAR ec_asn1_key[3 + ATCA_ECCP256_PUBKEY_SIZE] = { 0x04, 0x41, 0x04 }; + ATCA_STATUS status; - is_private = (ATCA_KEY_CONFIG_PRIVATE_MASK & pConfig->KeyConfig[obj_ptr->slot]); - } + if (is_private) + { + status = atcab_get_pubkey(obj_ptr->slot, &ec_asn1_key[3]); + PKCS11_DEBUG("atcab_get_pubkey: %x\r\n", status); + } + else + { + status = atcab_read_pubkey(obj_ptr->slot, &ec_asn1_key[3]); + PKCS11_DEBUG("atcab_read_pubkey: %x\r\n", status); + } - /* Only read from the device if there is someplace to store the result */ - if (is_private) - { - status = atcab_get_pubkey(obj_ptr->slot, &ec_asn1_key[3]); - PKCS11_DEBUG("atcab_get_pubkey: %x\r\n", status); - } - else - { - status = atcab_read_pubkey(obj_ptr->slot, &ec_asn1_key[3]); - PKCS11_DEBUG("atcab_read_pubkey: %x\r\n", status); + if (ATCA_SUCCESS == status) + { + rv = pkcs11_attrib_fill(pAttribute, ec_asn1_key, sizeof(ec_asn1_key)); + } + else + { + rv = CKR_FUNCTION_FAILED; + } + } } } - if (ATCA_SUCCESS == status) - { - return pkcs11_attrib_fill(pAttribute, ec_asn1_key, sizeof(ec_asn1_key)); - } - else - { - return CKR_FUNCTION_FAILED; - } + return rv; } static CK_RV pkcs11_key_get_secret(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute) @@ -292,6 +309,8 @@ static CK_RV pkcs11_key_get_secret_length(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR static CK_RV pkcs11_key_get_check_value(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute) { + return pkcs11_attrib_empty(NULL, pAttribute); +#if 0 pkcs11_object_ptr obj_ptr = (pkcs11_object_ptr)pObject; if (obj_ptr) @@ -310,6 +329,36 @@ static CK_RV pkcs11_key_get_check_value(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pA { return CKR_ARGUMENTS_BAD; } +#endif +} + +static CK_RV pkcs11_key_auth_required(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute) +{ + pkcs11_object_ptr obj_ptr = (pkcs11_object_ptr)pObject; + CK_RV rv = CKR_ARGUMENTS_BAD; + + if (obj_ptr) + { + if (atcab_is_ca_device(atcab_get_device_type())) + { +#if ATCA_CA_SUPPORT +#endif + } + else + { +#if ATCA_TA_SUPPORT + if (TA_PERM_ALWAYS != (obj_ptr->handle_info.permission & TA_PERM_USAGE_MASK) >> TA_PERM_USAGE_SHIFT) + { + rv = pkcs11_attrib_true(pObject, pAttribute); + } + else + { + rv = pkcs11_attrib_false(pObject, pAttribute); + } +#endif + } + } + return rv; } /** @@ -317,73 +366,73 @@ static CK_RV pkcs11_key_get_check_value(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pA */ const pkcs11_attrib_model pkcs11_key_public_attributes[] = { /** Object Class - CK_OBJECT_CLASS */ - { CKA_CLASS, pkcs11_object_get_class }, + { CKA_CLASS, pkcs11_object_get_class }, /** CK_TRUE if object is a token object; CK_FALSE if object is a session object. Default is CK_FALSE. */ - { CKA_TOKEN, pkcs11_attrib_true }, + { CKA_TOKEN, pkcs11_attrib_true }, /** CK_TRUE if object is a private object; CK_FALSE if object is a public object. */ - { CKA_PRIVATE, pkcs11_attrib_false }, + { CKA_PRIVATE, pkcs11_attrib_false }, /** CK_TRUE if object can be modified. Default is CK_TRUE. */ - { CKA_MODIFIABLE, pkcs11_token_get_writable }, + { CKA_MODIFIABLE, pkcs11_token_get_writable }, /** Description of the object(default empty). */ - { CKA_LABEL, pkcs11_object_get_name }, + { CKA_LABEL, pkcs11_object_get_name }, /** CK_TRUE if object can be copied using C_CopyObject.Defaults to CK_TRUE. */ - { CKA_COPYABLE, pkcs11_attrib_false }, + { CKA_COPYABLE, pkcs11_attrib_false }, /** CK_TRUE if the object can be destroyed using C_DestroyObject. Default is CK_TRUE. */ - { CKA_DESTROYABLE, pkcs11_object_get_destroyable }, + { CKA_DESTROYABLE, pkcs11_object_get_destroyable }, /** Type of key */ - { CKA_KEY_TYPE, pkcs11_object_get_type }, + { CKA_KEY_TYPE, pkcs11_object_get_type }, /** Key identifier for key (default empty) */ - { CKA_ID, pkcs11_attrib_empty }, + { CKA_ID, pkcs11_attrib_empty }, /** Start date for the key (default empty) */ - { CKA_START_DATE, pkcs11_attrib_empty }, + { CKA_START_DATE, pkcs11_attrib_empty }, /** End date for the key (default empty) */ - { CKA_END_DATE, pkcs11_attrib_empty }, + { CKA_END_DATE, pkcs11_attrib_empty }, /** CK_TRUE if key supports key derivation (i.e., if other keys can be derived from this one (default CK_FALSE) */ - { CKA_DERIVE, pkcs11_key_get_derivekey_flag }, + { CKA_DERIVE, pkcs11_key_get_derivekey_flag }, /** CK_TRUE only if key was either generated locally (i.e., on the token) with a C_GenerateKey or C_GenerateKeyPair call created with a C_CopyObject call as a copy of a key which had its CKA_LOCAL attribute set to CK_TRUE */ - { CKA_LOCAL, pkcs11_attrib_true }, + { CKA_LOCAL, pkcs11_attrib_true }, /** Identifier of the mechanism used to generate the key material. */ - { CKA_KEY_GEN_MECHANISM, NULL_PTR }, + { CKA_KEY_GEN_MECHANISM, NULL_PTR }, /** A list of mechanisms allowed to be used with this key. The number of mechanisms in the array is the ulValueLen component of the attribute divided by the size of CK_MECHANISM_TYPE. */ - { CKA_ALLOWED_MECHANISMS, pkcs11_key_get_allowed_mechanisms }, + { CKA_ALLOWED_MECHANISMS, pkcs11_key_get_allowed_mechanisms }, /** DER-encoding of the key subject name (default empty) */ - { CKA_SUBJECT, pkcs11_attrib_empty }, + { CKA_SUBJECT, pkcs11_attrib_empty }, /** CK_TRUE if key supports encryption */ - { CKA_ENCRYPT, NULL_PTR }, + { CKA_ENCRYPT, NULL_PTR }, /** CK_TRUE if key supports verification where the signature is an appendix to the data */ - { CKA_VERIFY, pkcs11_attrib_true }, + { CKA_VERIFY, pkcs11_attrib_true }, /** CK_TRUE if key supports verification where the data is recovered from the signature */ - { CKA_VERIFY_RECOVER, NULL_PTR }, + { CKA_VERIFY_RECOVER, NULL_PTR }, /** CK_TRUE if key supports wrapping (i.e., can be used to wrap other keys) */ - { CKA_WRAP, NULL_PTR }, + { CKA_WRAP, NULL_PTR }, /** The key can be trusted for the application that it was created. The wrapping key can be used to wrap keys with CKA_WRAP_WITH_TRUSTED set to CK_TRUE. */ - { CKA_TRUSTED, NULL_PTR }, + { CKA_TRUSTED, NULL_PTR }, /** For wrapping keys. The attribute template to match against any keys wrapped using this wrapping key. Keys that do not match cannot be wrapped. The number of attributes in the array is the ulValueLen component of the attribute divided by the size of CK_ATTRIBUTE. */ - { CKA_WRAP_TEMPLATE, NULL_PTR }, + { CKA_WRAP_TEMPLATE, NULL_PTR }, /** DER-encoding of the SubjectPublicKeyInfo for this public key. (MAY be empty, DEFAULT derived from the underlying public key data) SubjectPublicKeyInfo ::= SEQUENCE { algorithm AlgorithmIdentifier, subjectPublicKey BIT_STRING } */ - { CKA_PUBLIC_KEY_INFO, pkcs11_key_get_public_key }, + { CKA_PUBLIC_KEY_INFO, pkcs11_key_get_public_key }, /** DER - encoding of an ANSI X9.62 Parameters value Parameters ::= CHOICE { ecParameters ECParameters, namedCurve CURVES.&id({CurveNames}), implicitlyCA NULL } */ - { CKA_EC_PARAMS, pkcs11_key_get_ec_params }, + { CKA_EC_PARAMS, pkcs11_key_get_ec_params }, /** DER - encoding of ANSI X9.62 ECPoint value Q */ - { CKA_EC_POINT, pkcs11_key_get_ec_point }, + { CKA_EC_POINT, pkcs11_key_get_ec_point }, }; const CK_ULONG pkcs11_key_public_attributes_count = PKCS11_UTIL_ARRAY_SIZE(pkcs11_key_public_attributes); @@ -397,9 +446,9 @@ const pkcs11_attrib_model pkcs11_key_ec_public_attributes[] = { ecParameters ECParameters, namedCurve CURVES.&id({CurveNames}), implicitlyCA NULL } */ - { CKA_EC_PARAMS, pkcs11_key_get_ec_params }, + { CKA_EC_PARAMS, pkcs11_key_get_ec_params }, /** DER - encoding of ANSI X9.62 ECPoint value Q */ - { CKA_EC_POINT, pkcs11_key_get_ec_point }, + { CKA_EC_POINT, pkcs11_key_get_ec_point }, }; /** @@ -407,81 +456,81 @@ const pkcs11_attrib_model pkcs11_key_ec_public_attributes[] = { */ const pkcs11_attrib_model pkcs11_key_private_attributes[] = { /** Object Class - CK_OBJECT_CLASS */ - { CKA_CLASS, pkcs11_object_get_class }, + { CKA_CLASS, pkcs11_object_get_class }, /** CK_TRUE if object is a token object; CK_FALSE if object is a session object. Default is CK_FALSE. */ - { CKA_TOKEN, pkcs11_attrib_true }, + { CKA_TOKEN, pkcs11_attrib_true }, /** CK_TRUE if object is a private object; CK_FALSE if object is a public object. */ - { CKA_PRIVATE, pkcs11_attrib_true }, + { CKA_PRIVATE, pkcs11_attrib_true }, /** CK_TRUE if object can be modified. Default is CK_TRUE. */ - { CKA_MODIFIABLE, pkcs11_token_get_writable }, + { CKA_MODIFIABLE, pkcs11_token_get_writable }, /** Description of the object(default empty). */ - { CKA_LABEL, pkcs11_object_get_name }, + { CKA_LABEL, pkcs11_object_get_name }, /** CK_TRUE if object can be copied using C_CopyObject.Defaults to CK_TRUE. */ - { CKA_COPYABLE, pkcs11_attrib_false }, + { CKA_COPYABLE, pkcs11_attrib_false }, /** CK_TRUE if the object can be destroyed using C_DestroyObject. Default is CK_TRUE. */ - { CKA_DESTROYABLE, pkcs11_object_get_destroyable }, + { CKA_DESTROYABLE, pkcs11_object_get_destroyable }, /** Type of key */ - { CKA_KEY_TYPE, pkcs11_object_get_type }, + { CKA_KEY_TYPE, pkcs11_object_get_type }, /** Key identifier for key (default empty) */ - { CKA_ID, pkcs11_attrib_empty }, + { CKA_ID, pkcs11_attrib_empty }, /** Start date for the key (default empty) */ - { CKA_START_DATE, pkcs11_attrib_empty }, + { CKA_START_DATE, pkcs11_attrib_empty }, /** End date for the key (default empty) */ - { CKA_END_DATE, pkcs11_attrib_empty }, + { CKA_END_DATE, pkcs11_attrib_empty }, /** CK_TRUE if key supports key derivation (i.e., if other keys can be derived from this one (default CK_FALSE) */ - { CKA_DERIVE, pkcs11_key_get_derivekey_flag }, + { CKA_DERIVE, pkcs11_key_get_derivekey_flag }, /** CK_TRUE only if key was either generated locally (i.e., on the token) with a C_GenerateKey or C_GenerateKeyPair call created with a C_CopyObject call as a copy of a key which had its CKA_LOCAL attribute set to CK_TRUE */ - { CKA_LOCAL, pkcs11_key_get_local_flag }, + { CKA_LOCAL, pkcs11_key_get_local_flag }, /** Identifier of the mechanism used to generate the key material. */ - { CKA_KEY_GEN_MECHANISM, NULL_PTR }, + { CKA_KEY_GEN_MECHANISM, NULL_PTR }, /** A list of mechanisms allowed to be used with this key. The number of mechanisms in the array is the ulValueLen component of the attribute divided by the size of CK_MECHANISM_TYPE. */ - { CKA_ALLOWED_MECHANISMS, pkcs11_key_get_allowed_mechanisms }, + { CKA_ALLOWED_MECHANISMS, pkcs11_key_get_allowed_mechanisms }, /** DER-encoding of the key subject name (default empty) */ - { CKA_SUBJECT, pkcs11_attrib_empty }, + { CKA_SUBJECT, pkcs11_attrib_empty }, /** CK_TRUE if key is sensitive */ - { CKA_SENSITIVE, pkcs11_token_get_access_type }, + { CKA_SENSITIVE, pkcs11_token_get_access_type }, /** CK_TRUE if key supports decryption */ - { CKA_DECRYPT, NULL_PTR }, + { CKA_DECRYPT, NULL_PTR }, /** CK_TRUE if key supports signatures where the signature is an appendix to the data */ - { CKA_SIGN, pkcs11_attrib_true }, + { CKA_SIGN, pkcs11_attrib_true }, /** CK_TRUE if key supports signatures where the data can be recovered from the signature9 */ - { CKA_SIGN_RECOVER, NULL_PTR }, + { CKA_SIGN_RECOVER, NULL_PTR }, /** CK_TRUE if key supports unwrapping (i.e., can be used to unwrap other keys)9 */ - { CKA_UNWRAP, NULL_PTR }, + { CKA_UNWRAP, NULL_PTR }, /** CK_TRUE if key is extractable and can be wrapped 9 */ - { CKA_EXTRACTABLE, NULL_PTR }, + { CKA_EXTRACTABLE, NULL_PTR }, /** CK_TRUE if key has always had the CKA_SENSITIVE attribute set to CK_TRUE */ - { CKA_ALWAYS_SENSITIVE, pkcs11_token_get_access_type }, + { CKA_ALWAYS_SENSITIVE, pkcs11_token_get_access_type }, /** CK_TRUE if key has never had the CKA_EXTRACTABLE attribute set to CK_TRUE */ - { CKA_NEVER_EXTRACTABLE, NULL_PTR }, + { CKA_NEVER_EXTRACTABLE, NULL_PTR }, /** CK_TRUE if the key can only be wrapped with a wrapping key that has CKA_TRUSTED set to CK_TRUE. Default is CK_FALSE. */ - { CKA_WRAP_WITH_TRUSTED, NULL_PTR }, + { CKA_WRAP_WITH_TRUSTED, NULL_PTR }, /** For wrapping keys. The attribute template to match against any keys wrapped using this wrapping key. Keys that do not match cannot be wrapped. The number of attributes in the array is the ulValueLen component of the attribute divided by the size of CK_ATTRIBUTE. */ - { CKA_UNWRAP_TEMPLATE, NULL_PTR }, + { CKA_UNWRAP_TEMPLATE, NULL_PTR }, /** If CK_TRUE, the user has to supply the PIN for each use (sign or decrypt) with the key. Default is CK_FALSE. */ - { CKA_ALWAYS_AUTHENTICATE, pkcs11_attrib_false }, + { CKA_ALWAYS_AUTHENTICATE, pkcs11_key_auth_required }, /** DER-encoding of the SubjectPublicKeyInfo for the associated public key (MAY be empty; DEFAULT derived from the underlying private key data; MAY be manually set for specific key types; if set; MUST be consistent with the underlying private key data) */ - { CKA_PUBLIC_KEY_INFO, pkcs11_key_get_public_key }, + { CKA_PUBLIC_KEY_INFO, pkcs11_key_get_public_key }, /** DER - encoding of an ANSI X9.62 Parameters value Parameters ::= CHOICE { ecParameters ECParameters, namedCurve CURVES.&id({CurveNames}), implicitlyCA NULL } */ - { CKA_EC_PARAMS, pkcs11_key_get_ec_params }, + { CKA_EC_PARAMS, pkcs11_key_get_ec_params }, /** DER - encoding of ANSI X9.62 ECPoint value Q */ - { CKA_EC_POINT, pkcs11_key_get_ec_point }, + { CKA_EC_POINT, pkcs11_key_get_ec_point }, /** The value of the private key should remain private. A NULL function pointer is interpreted as a sensitive attribute. */ - { CKA_VALUE, NULL_PTR }, + { CKA_VALUE, NULL_PTR }, }; const CK_ULONG pkcs11_key_private_attributes_count = PKCS11_UTIL_ARRAY_SIZE(pkcs11_key_private_attributes); @@ -491,21 +540,21 @@ const CK_ULONG pkcs11_key_private_attributes_count = PKCS11_UTIL_ARRAY_SIZE(pkcs */ const pkcs11_attrib_model pkcs11_key_rsa_private_attributes[] = { /** Big integer Modulus n */ - { CKA_MODULUS, NULL_PTR }, + { CKA_MODULUS, NULL_PTR }, /** Big integer Public exponent e */ - { CKA_PUBLIC_EXPONENT, NULL_PTR }, + { CKA_PUBLIC_EXPONENT, NULL_PTR }, /** Big integer Private exponent d */ - { CKA_PRIVATE_EXPONENT, NULL_PTR }, + { CKA_PRIVATE_EXPONENT, NULL_PTR }, /** Big integer Prime p */ - { CKA_PRIME_1, NULL_PTR }, + { CKA_PRIME_1, NULL_PTR }, /** Big integer Prime q */ - { CKA_PRIME_2, NULL_PTR }, + { CKA_PRIME_2, NULL_PTR }, /** Big integer Private exponent d modulo p - 1 */ - { CKA_EXPONENT_1, NULL_PTR }, + { CKA_EXPONENT_1, NULL_PTR }, /** Big integer Private exponent d modulo q - 1 */ - { CKA_EXPONENT_2, NULL_PTR }, + { CKA_EXPONENT_2, NULL_PTR }, /** Big integer CRT coefficient q - 1 mod p */ - { CKA_COEFFICIENT, NULL_PTR }, + { CKA_COEFFICIENT, NULL_PTR }, }; /** @@ -517,9 +566,9 @@ const pkcs11_attrib_model pkcs11_key_ec_private_attributes[] = { ecParameters ECParameters, namedCurve CURVES.&id({CurveNames}), implicitlyCA NULL } */ - { CKA_EC_PARAMS, pkcs11_key_get_ec_params }, + { CKA_EC_PARAMS, pkcs11_key_get_ec_params }, /** DER - encoding of ANSI X9.62 ECPoint value Q */ - { CKA_EC_POINT, pkcs11_key_get_ec_point }, + { CKA_EC_POINT, pkcs11_key_get_ec_point }, }; @@ -528,483 +577,650 @@ const pkcs11_attrib_model pkcs11_key_ec_private_attributes[] = { */ const pkcs11_attrib_model pkcs11_key_secret_attributes[] = { /** Object Class - CK_OBJECT_CLASS */ - { CKA_CLASS, pkcs11_object_get_class }, + { CKA_CLASS, pkcs11_object_get_class }, /** CK_TRUE if object is a token object; CK_FALSE if object is a session object. Default is CK_FALSE. */ - { CKA_TOKEN, pkcs11_token_get_storage }, + { CKA_TOKEN, pkcs11_token_get_storage }, /** CK_TRUE if object is a private object; CK_FALSE if object is a public object. */ - { CKA_PRIVATE, pkcs11_token_get_access_type }, + { CKA_PRIVATE, pkcs11_token_get_access_type }, /** CK_TRUE if object can be modified. Default is CK_TRUE. */ - { CKA_MODIFIABLE, pkcs11_token_get_writable }, + { CKA_MODIFIABLE, pkcs11_token_get_writable }, /** Description of the object(default empty). */ - { CKA_LABEL, pkcs11_object_get_name }, + { CKA_LABEL, pkcs11_object_get_name }, /** CK_TRUE if object can be copied using C_CopyObject.Defaults to CK_TRUE. */ - { CKA_COPYABLE, pkcs11_attrib_false }, + { CKA_COPYABLE, pkcs11_attrib_false }, /** CK_TRUE if the object can be destroyed using C_DestroyObject. Default is CK_TRUE. */ - { CKA_DESTROYABLE, pkcs11_object_get_destroyable }, + { CKA_DESTROYABLE, pkcs11_object_get_destroyable }, /** Type of key */ - { CKA_KEY_TYPE, pkcs11_object_get_type }, + { CKA_KEY_TYPE, pkcs11_object_get_type }, /** Key identifier for key (default empty) */ - { CKA_ID, pkcs11_attrib_empty }, + { CKA_ID, pkcs11_attrib_empty }, /** Start date for the key (default empty) */ - { CKA_START_DATE, pkcs11_attrib_empty }, + { CKA_START_DATE, pkcs11_attrib_empty }, /** End date for the key (default empty) */ - { CKA_END_DATE, pkcs11_attrib_empty }, + { CKA_END_DATE, pkcs11_attrib_empty }, /** CK_TRUE if key supports key derivation (i.e., if other keys can be derived from this one (default CK_FALSE) */ - { CKA_DERIVE, pkcs11_attrib_true }, + { CKA_DERIVE, pkcs11_attrib_true }, /** CK_TRUE only if key was either generated locally (i.e., on the token) with a C_GenerateKey or C_GenerateKeyPair call created with a C_CopyObject call as a copy of a key which had its CKA_LOCAL attribute set to CK_TRUE */ - { CKA_LOCAL, pkcs11_key_get_local_flag }, + { CKA_LOCAL, pkcs11_key_get_local_flag }, /** Identifier of the mechanism used to generate the key material. */ - { CKA_KEY_GEN_MECHANISM, NULL_PTR }, + { CKA_KEY_GEN_MECHANISM, NULL_PTR }, /** A list of mechanisms allowed to be used with this key. The number of mechanisms in the array is the ulValueLen component of the attribute divided by the size of CK_MECHANISM_TYPE. */ - { CKA_ALLOWED_MECHANISMS, NULL_PTR }, + { CKA_ALLOWED_MECHANISMS, pkcs11_key_get_allowed_mechanisms }, /** CK_TRUE if key is sensitive */ - { CKA_SENSITIVE, pkcs11_token_get_access_type }, + { CKA_SENSITIVE, pkcs11_token_get_access_type }, /** CK_TRUE if key supports encryption */ - { CKA_ENCRYPT, NULL_PTR }, + { CKA_ENCRYPT, NULL_PTR }, /** CK_TRUE if key supports decryption */ - { CKA_DECRYPT, NULL_PTR }, + { CKA_DECRYPT, NULL_PTR }, /** CK_TRUE if key supports signatures (i.e., authentication codes) where the signature is an appendix to the data */ - { CKA_SIGN, NULL_PTR }, + { CKA_SIGN, NULL_PTR }, /** CK_TRUE if key supports verification (i.e., of authentication codes) where the signature is an appendix to the data */ - { CKA_VERIFY, NULL_PTR }, + { CKA_VERIFY, NULL_PTR }, /** CK_TRUE if key supports wrapping (i.e., can be used to wrap other keys) */ - { CKA_WRAP, NULL_PTR }, + { CKA_WRAP, NULL_PTR }, /** CK_TRUE if key supports unwrapping (i.e., can be used to unwrap other keys) */ - { CKA_UNWRAP, NULL_PTR }, + { CKA_UNWRAP, NULL_PTR }, /** CK_TRUE if key is extractable and can be wrapped */ - { CKA_EXTRACTABLE, NULL_PTR }, + { CKA_EXTRACTABLE, NULL_PTR }, /** CK_TRUE if key has always had the CKA_SENSITIVE attribute set to CK_TRUE */ - { CKA_ALWAYS_SENSITIVE, pkcs11_token_get_access_type }, + { CKA_ALWAYS_SENSITIVE, pkcs11_token_get_access_type }, /** CK_TRUE if key has never had the CKA_EXTRACTABLE attribute set to CK_TRUE */ - { CKA_NEVER_EXTRACTABLE, NULL_PTR }, + { CKA_NEVER_EXTRACTABLE, NULL_PTR }, /** Key checksum */ - { CKA_CHECK_VALUE, pkcs11_key_get_check_value }, + { CKA_CHECK_VALUE, pkcs11_key_get_check_value }, /** CK_TRUE if the key can only be wrapped with a wrapping key that has CKA_TRUSTED set to CK_TRUE. Default is CK_FALSE. */ - { CKA_WRAP_WITH_TRUSTED, NULL_PTR }, + { CKA_WRAP_WITH_TRUSTED, NULL_PTR }, /** The wrapping key can be used to wrap keys with CKA_WRAP_WITH_TRUSTED set to CK_TRUE. */ - { CKA_TRUSTED, NULL_PTR }, + { CKA_TRUSTED, NULL_PTR }, /** For wrapping keys. The attribute template to match against any keys wrapped using this wrapping key. Keys that do not match cannot be wrapped. The number of attributes in the array is the ulValueLen component of the attribute divided by the size of CK_ATTRIBUTE */ - { CKA_WRAP_TEMPLATE, NULL_PTR }, + { CKA_WRAP_TEMPLATE, NULL_PTR }, /** For wrapping keys. The attribute template to apply to any keys unwrapped using this wrapping key. Any user supplied template is applied after this template as if the object has already been created. The number of attributes in the array is the ulValueLen component of the attribute divided by the size of CK_ATTRIBUTE. */ - { CKA_UNWRAP_TEMPLATE, NULL_PTR }, + { CKA_UNWRAP_TEMPLATE, NULL_PTR }, /* Key value */ - { CKA_VALUE, pkcs11_key_get_secret }, + { CKA_VALUE, pkcs11_key_get_secret }, /* Length in bytes of the key */ - { CKA_VALUE_LEN, pkcs11_key_get_secret_length }, + { CKA_VALUE_LEN, pkcs11_key_get_secret_length }, }; const CK_ULONG pkcs11_key_secret_attributes_count = PKCS11_UTIL_ARRAY_SIZE(pkcs11_key_secret_attributes); -CK_RV pkcs11_key_write(CK_VOID_PTR pSession, CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute) + +static CK_RV pkcs11_key_privwrite_ca(CK_VOID_PTR pSession, pkcs11_object_ptr pObject, CK_VOID_PTR pValue, CK_ULONG ulValueLen) { - pkcs11_object_ptr obj_ptr = (pkcs11_object_ptr)pObject; - pkcs11_session_ctx_ptr session_ctx = (pkcs11_session_ctx_ptr)pSession; - atecc508a_config_t * cfg_ptr; - ATCA_STATUS status = ATCA_SUCCESS; +#if ATCA_CA_SUPPORT + CK_RV rv = CKR_ARGUMENTS_BAD; - if (!obj_ptr || !pAttribute || !pAttribute->pValue) + if (pSession && pObject && pValue && ulValueLen) { - return CKR_ARGUMENTS_BAD; + pkcs11_session_ctx_ptr session_ctx = (pkcs11_session_ctx_ptr)pSession; + uint8_t key_buf[36] = { 0, 0, 0, 0 }; + atecc508a_config_t* cfg_ptr = (atecc508a_config_t*)pObject->config; + + uint16_t write_key_id = cfg_ptr->SlotConfig[pObject->slot]; + write_key_id &= ATCA_SLOT_CONFIG_WRITE_KEY_MASK; + write_key_id >>= ATCA_SLOT_CONFIG_WRITE_KEY_SHIFT; + + memcpy(&key_buf[4], pValue, 32); + + /* Requires the io protection secret to be configured previously and for the + configuration to support this - should only be enabled for testing purposes. + Production devices should never have this feature enabled. */ + rv = pkcs11_util_convert_rv(atcab_priv_write(pObject->slot, key_buf, write_key_id, session_ctx->slot->read_key, NULL)); } - cfg_ptr = (atecc508a_config_t*)obj_ptr->config; + return rv; +#else + return CKR_GENERAL_ERROR; +#endif +} + + +CK_RV pkcs11_key_write(CK_VOID_PTR pSession, CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute) +{ + pkcs11_object_ptr obj_ptr = (pkcs11_object_ptr)pObject; + CK_RV rv = CKR_ARGUMENTS_BAD; - if (obj_ptr->class_id == CKO_PUBLIC_KEY && pAttribute->type == CKA_EC_POINT) + if (obj_ptr && pAttribute && pAttribute->pValue) { - if (!memcmp(ec_x962_asn1_header, pAttribute->pValue, sizeof(ec_x962_asn1_header))) + if (obj_ptr->class_id == CKO_PUBLIC_KEY && pAttribute->type == CKA_EC_POINT) { - if (cfg_ptr->KeyConfig[obj_ptr->slot] & ATCA_KEY_CONFIG_PRIVATE_MASK) + if (!memcmp(ec_x962_asn1_header, pAttribute->pValue, sizeof(ec_x962_asn1_header))) { - /* Assume it is paired with the private key that was stored */ - return CKR_OK; + CK_BBOOL is_private; + + if (CKR_OK == (rv = pkcs11_object_is_private(obj_ptr, &is_private))) + { + if (is_private) + { + /* Assume it is paired with the private key that is already stored */ + rv = CKR_OK; + } + else + { + /* Actually write the public key into the slot */ + rv = pkcs11_util_convert_rv(atcab_write_pubkey(obj_ptr->slot, &(((uint8_t*)pAttribute->pValue)[sizeof(ec_x962_asn1_header)]))); + } + } } - else + } + else if (obj_ptr->class_id == CKO_PRIVATE_KEY && pAttribute->type == CKA_VALUE) + { + if (atcab_is_ca_device(atcab_get_device_type())) { - /* Actually write the public key into the slot */ - status = atcab_write_pubkey(obj_ptr->slot, &(((uint8_t*)pAttribute->pValue)[sizeof(ec_x962_asn1_header)])); + rv = pkcs11_key_privwrite_ca(pSession, obj_ptr, pAttribute->pValue, pAttribute->ulValueLen); } } - else + else if (obj_ptr->class_id == CKO_SECRET_KEY && pAttribute->type == CKA_VALUE) { - return CKR_ARGUMENTS_BAD; + if ((cfg_ptr->SlotConfig[obj_ptr->slot] & ATCA_SLOT_CONFIG_IS_SECRET_MASK) && + (pAttribute->ulValueLen % 32) != 0) + { + uint8_t buf[64] = { 0 }; + uint16_t buflen = (pAttribute->ulValueLen / 32) ? 64 : 32; + if (pAttribute->ulValueLen > 64) + { + return CKR_ATTRIBUTE_VALUE_INVALID; + } + memcpy(buf, pAttribute->pValue, pAttribute->ulValueLen); + rv = pkcs11_util_convert_rv(atcab_write_bytes_zone(ATCA_ZONE_DATA, obj_ptr->slot, 0, buf, buflen)); + } + else + { + rv = pkcs11_util_convert_rv(atcab_write_bytes_zone(ATCA_ZONE_DATA, obj_ptr->slot, 0, pAttribute->pValue, pAttribute->ulValueLen)); + } } } - else if (obj_ptr->class_id == CKO_PRIVATE_KEY && pAttribute->type == CKA_VALUE) + + CK_RV pkcs11_key_generate + ( + CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulCount, + CK_OBJECT_HANDLE_PTR phKey + ) { - uint8_t key_buf[36] = { 0, 0, 0, 0 }; - uint16_t write_key_id = cfg_ptr->SlotConfig[obj_ptr->slot]; - write_key_id &= ATCA_SLOT_CONFIG_WRITE_KEY_MASK; - write_key_id >>= ATCA_SLOT_CONFIG_WRITE_KEY_SHIFT; + CK_ATTRIBUTE_PTR pName = NULL; + pkcs11_lib_ctx_ptr pLibCtx; + pkcs11_session_ctx_ptr pSession; + pkcs11_object_ptr pKey = NULL; + uint8_t buf[32]; + int i; + CK_RV rv = CKR_OK; + ATCA_STATUS status = ATCA_SUCCESS; + + rv = pkcs11_init_check(&pLibCtx, FALSE); + if (rv) + { + return rv; + } - memcpy(&key_buf[4], pAttribute->pValue, 32); + if (!pMechanism || !pTemplate || !ulCount || !phKey) + { + return CKR_ARGUMENTS_BAD; + } - /* Requires the io protection secret to be configured previously and for the - configuration to support this - should only be enabled for testing purposes. - Production devices should never have this feature enabled. */ - status = atcab_priv_write(obj_ptr->slot, key_buf, write_key_id, session_ctx->read_key, NULL); - } - else - { - return CKR_ARGUMENTS_BAD; - } + rv = pkcs11_session_check(&pSession, hSession); + if (rv) + { + return rv; + } - if (ATCA_SUCCESS == status) - { - return CKR_OK; - } - else - { - return CKR_GENERAL_ERROR; - } -} + /* @todo Perform the various mechanism and key attribute checks */ -CK_RV pkcs11_key_generate_pair -( - CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism, - CK_ATTRIBUTE_PTR pPublicKeyTemplate, - CK_ULONG ulPublicKeyAttributeCount, - CK_ATTRIBUTE_PTR pPrivateKeyTemplate, - CK_ULONG ulPrivateKeyAttributeCount, - CK_OBJECT_HANDLE_PTR phPublicKey, - CK_OBJECT_HANDLE_PTR phPrivateKey -) -{ - CK_ATTRIBUTE_PTR pName = NULL; - pkcs11_lib_ctx_ptr pLibCtx; - pkcs11_session_ctx_ptr pSession; - pkcs11_object_ptr pPublic = NULL; - pkcs11_object_ptr pPrivate = NULL; - int i; - CK_RV rv = CKR_OK; - - rv = pkcs11_init_check(&pLibCtx, FALSE); - if (rv) - { - return rv; - } + if ((CKM_AES_KEY_GEN != pMechanism->mechanism) && + (CKM_SHA256_HMAC != pMechanism->mechanism)) + { + return CKR_MECHANISM_INVALID; + } - if (!pMechanism || !pPublicKeyTemplate || !ulPublicKeyAttributeCount || - !pPrivateKeyTemplate || !ulPrivateKeyAttributeCount || - !phPublicKey || !phPrivateKey) - { - return CKR_ARGUMENTS_BAD; - } - rv = pkcs11_session_check(&pSession, hSession); - if (rv) - { - return rv; - } + for (i = 0; i < ulCount; i++) + { + if (CKA_LABEL == pTemplate[i].type) + { + pName = &pTemplate[i]; + break; + } + } - /* @todo Perform the various mechanism and key attribute checks */ + if (!pName || pName->ulValueLen > PKCS11_MAX_LABEL_SIZE) + { + return CKR_TEMPLATE_INCONSISTENT; + } - if (CKM_EC_KEY_PAIR_GEN != pMechanism->mechanism) - { - return CKR_MECHANISM_INVALID; - } + /* Must create two new objects - a public and private key */ + if (CKR_OK == rv) + { + rv = pkcs11_object_alloc(&pKey); + } - for (i = 0; i < ulPrivateKeyAttributeCount; i++) - { - if (CKA_LABEL == pPrivateKeyTemplate[i].type) + if (CKR_OK == rv) { - pName = &pPrivateKeyTemplate[i]; - break; + pKey->class_id = CKO_SECRET_KEY; + rv = pkcs11_config_key(pLibCtx, pSession->slot, pKey, pName); } - } - if (!pName || pName->ulValueLen > PKCS11_MAX_LABEL_SIZE) - { - return CKR_TEMPLATE_INCONSISTENT; - } + if (CKR_OK == rv) + { + if (CKR_OK == (rv = pkcs11_lock_context(pLibCtx))) + { + atecc508a_config_t * pConfig = (atecc508a_config_t*)pKey->config; - /* Must create two new objects - a public and private key */ + if (pConfig->KeyConfig[pKey->slot] & 0x0018) + { + if (pConfig->SlotConfig[pKey->slot] & 0x2000) + { + if (ATCA_SUCCESS == (status = atcab_nonce_rand(buf, NULL))) + { + status = atcab_derivekey(0, pKey->slot, NULL); + } + } + else + { + if (ATCA_SUCCESS == (status = atcab_random(buf))) + { + status = atcab_write_bytes_zone(ATCA_ZONE_DATA, pKey->slot, 0, buf, 32); + } + } + } + (void)pkcs11_unlock_context(pLibCtx); + } + } - if (CKR_OK == rv) - { - rv = pkcs11_object_alloc(&pPrivate); - } + if (CKR_OK == rv && ATCA_SUCCESS != status) + { + (void)pkcs11_config_remove_object(pLibCtx, pSession->slot, pKey); + rv = pkcs11_util_convert_rv(status); + } - if (CKR_OK == rv) - { - rv = pkcs11_object_alloc(&pPublic); + if (CKR_OK == rv) + { + pkcs11_object_get_handle(pKey, phKey); + } + else + { + if (pKey) + { + pkcs11_object_free(pKey); + } + } + + return rv; } - if (CKR_OK == rv) + CK_RV pkcs11_key_generate_pair + ( + CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_ATTRIBUTE_PTR pPublicKeyTemplate, + CK_ULONG ulPublicKeyAttributeCount, + CK_ATTRIBUTE_PTR pPrivateKeyTemplate, + CK_ULONG ulPrivateKeyAttributeCount, + CK_OBJECT_HANDLE_PTR phPublicKey, + CK_OBJECT_HANDLE_PTR phPrivateKey + ) { - if (!pPublic || !pPrivate) + CK_ATTRIBUTE_PTR pName = NULL; + pkcs11_lib_ctx_ptr pLibCtx; + pkcs11_session_ctx_ptr pSession; + pkcs11_object_ptr pPublic = NULL; + pkcs11_object_ptr pPrivate = NULL; + int i; + CK_RV rv = CKR_OK; + + rv = pkcs11_init_check(&pLibCtx, FALSE); + if (rv) { - rv = CKR_TEMPLATE_INCONSISTENT; + return rv; } - } - if (CKR_OK == rv) - { - pPrivate->class_id = CKO_PRIVATE_KEY; - rv = pkcs11_config_key(pLibCtx, pSession->slot, pPrivate, pName); - } + if (!pMechanism || !pPublicKeyTemplate || !ulPublicKeyAttributeCount || + !pPrivateKeyTemplate || !ulPrivateKeyAttributeCount || + !phPublicKey || !phPrivateKey) + { + return CKR_ARGUMENTS_BAD; + } - if (CKR_OK == rv) - { - pPublic->slot = pPrivate->slot; - pPublic->flags = pPrivate->flags; - memcpy(pPublic->name, pName->pValue, pName->ulValueLen); - pPublic->class_id = CKO_PUBLIC_KEY; - pPublic->class_type = CKK_EC; - pPublic->attributes = pkcs11_key_public_attributes; - pPublic->count = pkcs11_key_public_attributes_count; - pPublic->size = 64; - pPublic->config = &((pkcs11_slot_ctx_ptr)pSession->slot)->cfg_zone; + rv = pkcs11_session_check(&pSession, hSession); + if (rv) + { + return rv; + } - if (CKR_OK == (rv = pkcs11_lock_context(pLibCtx))) + /* @todo Perform the various mechanism and key attribute checks */ + + if (CKM_EC_KEY_PAIR_GEN != pMechanism->mechanism) { - rv = pkcs11_util_convert_rv(atcab_genkey(pPrivate->slot, NULL)); - (void)pkcs11_unlock_context(pLibCtx); + return CKR_MECHANISM_INVALID; } - } - if (CKR_OK == rv) - { - pkcs11_object_get_handle(pPrivate, phPrivateKey); - pkcs11_object_get_handle(pPublic, phPublicKey); - } - else - { - if (pPrivate) + + for (i = 0; i < ulPrivateKeyAttributeCount; i++) { - pkcs11_object_free(pPrivate); + if (CKA_LABEL == pPrivateKeyTemplate[i].type) + { + pName = &pPrivateKeyTemplate[i]; + break; + } } - if (pPublic) + + if (!pName || pName->ulValueLen > PKCS11_MAX_LABEL_SIZE) { - pkcs11_object_free(pPublic); + return CKR_TEMPLATE_INCONSISTENT; } - } - return rv; -} + /* Must create two new objects - a public and private key */ -#ifdef ATCA_NO_HEAP -static uint8_t pkcs11_key_cache[32]; + if (CKR_OK == rv) + { + rv = pkcs11_object_alloc(&pPrivate); + } -static uint8_t pkcs11_key_used(uint8_t * key, size_t keylen) -{ - if (key) - { - for (int i = 0; i < keylen; i++) + if (CKR_OK == rv) { - if (key[i]) + rv = pkcs11_object_alloc(&pPublic); + } + + if (CKR_OK == rv) + { + if (!pPublic || !pPrivate) { - return 1; + rv = CKR_TEMPLATE_INCONSISTENT; } } - } - return 0; -} -#endif -CK_RV pkcs11_key_derive -( - CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism, - CK_OBJECT_HANDLE hBaseKey, - CK_ATTRIBUTE_PTR pTemplate, - CK_ULONG ulCount, - CK_OBJECT_HANDLE_PTR phKey -) -{ - pkcs11_session_ctx_ptr pSession = NULL; - pkcs11_lib_ctx_ptr pLibCtx; - pkcs11_object_ptr pBaseKey = NULL; - pkcs11_object_ptr pSecretKey = NULL; - CK_ECDH1_DERIVE_PARAMS_PTR pEcdhParameters = NULL; - CK_RV rv = CKR_OK; - - rv = pkcs11_init_check(&pLibCtx, FALSE); - if (rv) - { - return rv; - } + if (CKR_OK == rv) + { + pPrivate->class_id = CKO_PRIVATE_KEY; + rv = pkcs11_config_key(pLibCtx, pSession->slot, pPrivate, pName); + } - if (!hSession || !pMechanism || !hBaseKey || - !pTemplate || !ulCount || !phKey) - { - return CKR_ARGUMENTS_BAD; - } + if (CKR_OK == rv) + { + pPublic->slot = pPrivate->slot; + pPublic->flags = pPrivate->flags; + memcpy(pPublic->name, pName->pValue, pName->ulValueLen); + pPublic->class_id = CKO_PUBLIC_KEY; + pPublic->class_type = CKK_EC; + pPublic->attributes = pkcs11_key_public_attributes; + pPublic->count = pkcs11_key_public_attributes_count; + pPublic->size = 64; +#if ATCA_CA_SUPPORT + pPublic->config = &((pkcs11_slot_ctx_ptr)pSession->slot)->cfg_zone; +#endif - *phKey = CK_INVALID_HANDLE; + if (CKR_OK == (rv = pkcs11_lock_context(pLibCtx))) + { + rv = pkcs11_util_convert_rv(atcab_genkey(pPrivate->slot, NULL)); + if (rv) + { + (void)pkcs11_config_remove_object(pLibCtx, pSession->slot, pPrivate); + } + (void)pkcs11_unlock_context(pLibCtx); + } + } - if (CKM_ECDH1_DERIVE == pMechanism->mechanism || CKM_ECDH1_COFACTOR_DERIVE == pMechanism->mechanism) - { - if (sizeof(CK_ECDH1_DERIVE_PARAMS) != pMechanism->ulParameterLen || - !pMechanism->pParameter) + if (CKR_OK == rv) { - rv = CKR_ARGUMENTS_BAD; + pkcs11_object_get_handle(pPrivate, phPrivateKey); + pkcs11_object_get_handle(pPublic, phPublicKey); } else { - pEcdhParameters = (CK_ECDH1_DERIVE_PARAMS_PTR)pMechanism->pParameter; - if (!pEcdhParameters->pPublicData) + if (pPrivate) { - rv = CKR_ARGUMENTS_BAD; + pkcs11_object_free(pPrivate); + } + if (pPublic) + { + pkcs11_object_free(pPublic); } } - } - else - { - rv = CKR_FUNCTION_NOT_SUPPORTED; - } - if (CKR_OK == rv) - { - rv = pkcs11_session_check(&pSession, hSession); + return rv; } - if (CKR_OK == rv) - { - rv = pkcs11_object_check(&pBaseKey, hBaseKey); - } +#ifdef ATCA_NO_HEAP + static uint8_t pkcs11_key_cache[32]; - if (CKR_OK == rv) + static uint8_t pkcs11_key_used(uint8_t * key, size_t keylen) { - rv = pkcs11_object_alloc(&pSecretKey); + if (key) + { + for (int i = 0; i < keylen; i++) + { + if (key[i]) + { + return 1; + } + } + } + return 0; } +#endif - for (int i = 0; (i < ulCount) && (CKR_OK == rv); i++) + static CK_RV pkcs11_key_derive_ca(pkcs11_session_ctx_ptr pSession, pkcs11_object_ptr pBaseKey, pkcs11_object_ptr pSecretKey, CK_ECDH1_DERIVE_PARAMS_PTR pEcdhParameters) { - if (CKA_LABEL == pTemplate[i].type) +#if ATCA_CA_SUPPORT + CK_RV rv = CKR_ARGUMENTS_BAD; + + if (pSession && pBaseKey && pSecretKey && pEcdhParameters) { - if (pTemplate[i].pValue && pTemplate[i].ulValueLen > PKCS11_MAX_LABEL_SIZE) - { - rv = CKR_TEMPLATE_INCONSISTENT; - } - else + pkcs11_lib_ctx_ptr pLibCtx = pkcs11_get_context(); + + /* Use the tempkey slot id */ + pSecretKey->slot = ATCA_TEMPKEY_KEYID; + pSecretKey->attributes = pkcs11_key_secret_attributes; + pSecretKey->count = pkcs11_key_secret_attributes_count; + pSecretKey->size = 32; + pSecretKey->config = &((pkcs11_slot_ctx_ptr)pSession->slot)->cfg_zone; + pSecretKey->flags = PKCS11_OBJECT_FLAG_DESTROYABLE | PKCS11_OBJECT_FLAG_SENSITIVE; +#ifdef ATCA_NO_HEAP + if (!pkcs11_key_used(pkcs11_key_cache, sizeof(pkcs11_key_cache))) { - memcpy(pSecretKey->name, pTemplate[i].pValue, pTemplate[i].ulValueLen); + pSecretKey->data = pkcs11_key_cache; } - } - else if (CKA_CLASS == pTemplate[i].type) - { - if (sizeof(pSecretKey->class_id) != pTemplate[i].ulValueLen) +#else + pSecretKey->data = pkcs11_os_malloc(pSecretKey->size); +#endif + if (!pSecretKey->data) { - rv = CKR_TEMPLATE_INCONSISTENT; + rv = CKR_HOST_MEMORY; } - else + + if (CKR_OK == (rv = pkcs11_lock_context(pLibCtx))) { - memcpy(&pSecretKey->class_id, pTemplate[i].pValue, sizeof(pSecretKey->class_id)); + ATCA_STATUS status = ATCA_SUCCESS; + + /* Because of the number of ECDH options this function unfortunately has a complex bit of logic + to walk through to select the proper ECDH command. Normally this would be left up to the user + to chose */ + + if (ATCA_TEMPKEY_KEYID == pBaseKey->slot) + { + if (pSession->slot->logged_in) + { + status = atcab_ecdh_tempkey_ioenc(&pEcdhParameters->pPublicData[1], pSecretKey->data, pSession->slot->read_key); + } + else + { + status = atcab_ecdh_tempkey(&pEcdhParameters->pPublicData[1], pSecretKey->data); + } + } + else if (16 > pBaseKey->slot) + { + if (ATCA_SLOT_CONFIG_WRITE_ECDH_MASK & pSession->slot->cfg_zone.SlotConfig[pBaseKey->slot]) + { + uint16_t read_key_id = (ATCA_SLOT_CONFIG_READKEY_MASK & pSession->slot->cfg_zone.SlotConfig[pBaseKey->slot | 0x01]) + >> ATCA_SLOT_CONFIG_READKEY_SHIFT; + status = atcab_ecdh_enc(pBaseKey->slot, &pEcdhParameters->pPublicData[1], pSecretKey->data, + pSession->slot->read_key, read_key_id, NULL); + } + else if ((ATECC508A != pSession->slot->interface_config.devtype) && + (ATCA_CHIP_OPT_IO_PROT_EN_MASK & pSession->slot->cfg_zone.ChipOptions) && + pSession->slot->logged_in) + { + status = atcab_ecdh_ioenc(pBaseKey->slot, &pEcdhParameters->pPublicData[1], pSecretKey->data, pSession->slot->read_key); + } + else + { + status = atcab_ecdh(pBaseKey->slot, &pEcdhParameters->pPublicData[1], pSecretKey->data); + } + } + else + { + status = ATCA_GEN_FAIL; + } + + (void)pkcs11_unlock_context(pLibCtx); + + rv = pkcs11_util_convert_rv(status); } } - else if (CKA_KEY_TYPE == pTemplate[i].type) + + return rv; +#else + return CKR_GENERAL_ERROR; +#endif + } + + CK_RV pkcs11_key_derive + ( + CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hBaseKey, + CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulCount, + CK_OBJECT_HANDLE_PTR phKey + ) + { + pkcs11_session_ctx_ptr pSession = NULL; + pkcs11_lib_ctx_ptr pLibCtx; + pkcs11_object_ptr pBaseKey = NULL; + pkcs11_object_ptr pSecretKey = NULL; + CK_ECDH1_DERIVE_PARAMS_PTR pEcdhParameters = NULL; + CK_RV rv = CKR_OK; + + rv = pkcs11_init_check(&pLibCtx, FALSE); + if (rv) { - if (sizeof(pSecretKey->class_type) != pTemplate[i].ulValueLen) + return rv; + } + + if (!hSession || !pMechanism || !hBaseKey || + !pTemplate || !ulCount || !phKey) + { + return CKR_ARGUMENTS_BAD; + } + + *phKey = CK_INVALID_HANDLE; + + if (CKM_ECDH1_DERIVE == pMechanism->mechanism || CKM_ECDH1_COFACTOR_DERIVE == pMechanism->mechanism) + { + if (sizeof(CK_ECDH1_DERIVE_PARAMS) != pMechanism->ulParameterLen || + !pMechanism->pParameter) { - rv = CKR_TEMPLATE_INCONSISTENT; + rv = CKR_ARGUMENTS_BAD; } else { - memcpy(&pSecretKey->class_type, pTemplate[i].pValue, sizeof(pSecretKey->class_type)); + pEcdhParameters = (CK_ECDH1_DERIVE_PARAMS_PTR)pMechanism->pParameter; + if (!pEcdhParameters->pPublicData) + { + rv = CKR_ARGUMENTS_BAD; + } } } - } - - if (CKR_OK == rv) - { - /* Use the tempkey slot id */ - pSecretKey->slot = ATCA_TEMPKEY_KEYID; - pSecretKey->attributes = pkcs11_key_secret_attributes; - pSecretKey->count = pkcs11_key_secret_attributes_count; - pSecretKey->size = 32; - pSecretKey->config = &((pkcs11_slot_ctx_ptr)pSession->slot)->cfg_zone; - pSecretKey->flags = PKCS11_OBJECT_FLAG_DESTROYABLE | PKCS11_OBJECT_FLAG_SENSITIVE; -#ifdef ATCA_NO_HEAP - if (!pkcs11_key_used(pkcs11_key_cache, sizeof(pkcs11_key_cache))) + else { - pSecretKey->data = pkcs11_key_cache; + rv = CKR_FUNCTION_NOT_SUPPORTED; } -#else - pSecretKey->data = pkcs11_os_malloc(pSecretKey->size); -#endif - if (!pSecretKey->data) + + if (CKR_OK == rv) { - rv = CKR_HOST_MEMORY; + rv = pkcs11_session_check(&pSession, hSession); } - } - if (CKR_OK == rv) - { - if (CKR_OK == (rv = pkcs11_lock_context(pLibCtx))) + if (CKR_OK == rv) { - ATCA_STATUS status = ATCA_SUCCESS; + rv = pkcs11_object_check(&pBaseKey, hBaseKey); + } - /* Because of the number of ECDH options this function unfortunately has a complex bit of logic - to walk through to select the proper ECDH command. Normally this would be left up to the user - to chose */ + if (CKR_OK == rv) + { + rv = pkcs11_object_alloc(&pSecretKey); + } - if (ATCA_TEMPKEY_KEYID == pBaseKey->slot) + for (int i = 0; (i < ulCount) && (CKR_OK == rv); i++) + { + if (CKA_LABEL == pTemplate[i].type) { - if (pSession->logged_in) + if (pTemplate[i].pValue && pTemplate[i].ulValueLen > PKCS11_MAX_LABEL_SIZE) { - status = atcab_ecdh_tempkey_ioenc(&pEcdhParameters->pPublicData[1], pSecretKey->data, pSession->read_key); + rv = CKR_TEMPLATE_INCONSISTENT; } - else + else if (pTemplate[i].pValue && pTemplate[i].ulValueLen) { - status = atcab_ecdh_tempkey(&pEcdhParameters->pPublicData[1], pSecretKey->data); + memcpy(pSecretKey->name, pTemplate[i].pValue, pTemplate[i].ulValueLen); } } - else if (16 > pBaseKey->slot) + else if (CKA_CLASS == pTemplate[i].type) { - if (ATCA_SLOT_CONFIG_WRITE_ECDH_MASK & pSession->slot->cfg_zone.SlotConfig[pBaseKey->slot]) + if (sizeof(pSecretKey->class_id) != pTemplate[i].ulValueLen) { - uint16_t read_key_id = (ATCA_SLOT_CONFIG_READKEY_MASK & pSession->slot->cfg_zone.SlotConfig[pBaseKey->slot | 0x01]) - >> ATCA_SLOT_CONFIG_READKEY_SHIFT; - status = atcab_ecdh_enc(pBaseKey->slot, &pEcdhParameters->pPublicData[1], pSecretKey->data, - pSession->read_key, read_key_id, NULL); + rv = CKR_TEMPLATE_INCONSISTENT; } - else if ((ATECC508A != pSession->slot->interface_config.devtype) && - (ATCA_CHIP_OPT_IO_PROT_EN_MASK & pSession->slot->cfg_zone.ChipOptions) && - pSession->logged_in) + else { - status = atcab_ecdh_ioenc(pBaseKey->slot, &pEcdhParameters->pPublicData[1], pSecretKey->data, pSession->read_key); + memcpy(&pSecretKey->class_id, pTemplate[i].pValue, sizeof(pSecretKey->class_id)); + } + } + else if (CKA_KEY_TYPE == pTemplate[i].type) + { + if (sizeof(pSecretKey->class_type) != pTemplate[i].ulValueLen) + { + rv = CKR_TEMPLATE_INCONSISTENT; } else { - status = atcab_ecdh(pBaseKey->slot, &pEcdhParameters->pPublicData[1], pSecretKey->data); + memcpy(&pSecretKey->class_type, pTemplate[i].pValue, sizeof(pSecretKey->class_type)); } } - else + } + + if (CKR_OK == rv) + { + if (atcab_is_ca_device(atcab_get_device_type())) { - status = ATCA_GEN_FAIL; + rv = pkcs11_key_derive_ca(pSession, pBaseKey, pSecretKey, pEcdhParameters); } + } - (void)pkcs11_unlock_context(pLibCtx); - - rv = pkcs11_util_convert_rv(status); + if (CKR_OK == rv) + { + pkcs11_object_get_handle(pSecretKey, phKey); + } + else if (pSecretKey) + { + pkcs11_object_free(pSecretKey); } - } - if (CKR_OK == rv) - { - pkcs11_object_get_handle(pSecretKey, phKey); - } - else if (pSecretKey) - { - pkcs11_object_free(pSecretKey); + return rv; } - return rv; -} - /** @} */ diff --git a/lib/pkcs11/pkcs11_key.h b/lib/pkcs11/pkcs11_key.h index da871a318..f3d6e3d51 100644 --- a/lib/pkcs11/pkcs11_key.h +++ b/lib/pkcs11/pkcs11_key.h @@ -48,6 +48,8 @@ extern const pkcs11_attrib_model pkcs11_key_secret_attributes[]; extern const CK_ULONG pkcs11_key_secret_attributes_count; CK_RV pkcs11_key_write(CK_VOID_PTR pSession, CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute); +CK_RV pkcs11_key_generate(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey); CK_RV pkcs11_key_generate_pair(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_ULONG ulPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_ULONG ulPrivateKeyAttributeCount, diff --git a/lib/pkcs11/pkcs11_main.c b/lib/pkcs11/pkcs11_main.c index 0d13b77ad..68f8d299c 100644 --- a/lib/pkcs11/pkcs11_main.c +++ b/lib/pkcs11/pkcs11_main.c @@ -36,6 +36,7 @@ /* Cryptoauthlib Interface Includes */ #include "pkcs11_config.h" #include "pkcs11_debug.h" +#include "pkcs11_encrypt.h" #include "pkcs11_init.h" #include "pkcs11_info.h" #include "pkcs11_slot.h" @@ -462,25 +463,24 @@ CK_RV C_EncryptInit CK_OBJECT_HANDLE hObject ) { - ((void)hSession); - ((void)pMechanism); - ((void)hObject); PKCS11_DEBUG("\r\n"); - PKCS11_DEBUG_RETURN(CKR_FUNCTION_NOT_SUPPORTED); + PKCS11_DEBUG_RETURN(pkcs11_encrypt_init(hSession, pMechanism, hObject)); } /** * \brief Perform a single operation encryption operation in the specified session */ -CK_RV C_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen) +CK_RV C_Encrypt +( + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pData, + CK_ULONG ulDataLen, + CK_BYTE_PTR pEncryptedData, + CK_ULONG_PTR pulEncryptedDataLen +) { - ((void)hSession); - ((void)pData); - ((void)ulDataLen); - ((void)pEncryptedData); - ((void)pulEncryptedDataLen); PKCS11_DEBUG("\r\n"); - PKCS11_DEBUG_RETURN(CKR_FUNCTION_NOT_SUPPORTED); + PKCS11_DEBUG_RETURN(pkcs11_encrypt(hSession, pData, ulDataLen, pEncryptedData, pulEncryptedDataLen)); } /** @@ -495,13 +495,8 @@ CK_RV C_EncryptUpdate CK_ULONG_PTR pulEncryptedDataLen ) { - ((void)hSession); - ((void)pData); - ((void)ulDataLen); - ((void)pEncryptedData); - ((void)pulEncryptedDataLen); PKCS11_DEBUG("\r\n"); - PKCS11_DEBUG_RETURN(CKR_FUNCTION_NOT_SUPPORTED); + PKCS11_DEBUG_RETURN(pkcs11_encrypt_update(hSession, pData, ulDataLen, pEncryptedData, pulEncryptedDataLen)); } /** @@ -509,11 +504,8 @@ CK_RV C_EncryptUpdate */ CK_RV C_EncryptFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen) { - ((void)hSession); - ((void)pEncryptedData); - ((void)pulEncryptedDataLen); PKCS11_DEBUG("\r\n"); - PKCS11_DEBUG_RETURN(CKR_FUNCTION_NOT_SUPPORTED); + PKCS11_DEBUG_RETURN(pkcs11_encrypt_final(hSession, pEncryptedData, pulEncryptedDataLen)); } /** @@ -521,11 +513,8 @@ CK_RV C_EncryptFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, CK_ */ CK_RV C_DecryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hObject) { - ((void)hSession); - ((void)pMechanism); - ((void)hObject); PKCS11_DEBUG("\r\n"); - PKCS11_DEBUG_RETURN(CKR_FUNCTION_NOT_SUPPORTED); + PKCS11_DEBUG_RETURN(pkcs11_decrypt_init(hSession, pMechanism, hObject)); } /** @@ -540,13 +529,8 @@ CK_RV C_Decrypt CK_ULONG_PTR pulDataLen ) { - ((void)hSession); - ((void)pEncryptedData); - ((void)ulEncryptedDataLen); - ((void)pData); - ((void)pulDataLen); PKCS11_DEBUG("\r\n"); - PKCS11_DEBUG_RETURN(CKR_FUNCTION_NOT_SUPPORTED); + PKCS11_DEBUG_RETURN(pkcs11_decrypt(hSession, pEncryptedData, ulEncryptedDataLen, pData, pulDataLen)); } /** @@ -561,13 +545,8 @@ CK_RV C_DecryptUpdate CK_ULONG_PTR pDataLen ) { - ((void)hSession); - ((void)pEncryptedData); - ((void)ulEncryptedDataLen); - ((void)pData); - ((void)pDataLen); PKCS11_DEBUG("\r\n"); - PKCS11_DEBUG_RETURN(CKR_FUNCTION_NOT_SUPPORTED); + PKCS11_DEBUG_RETURN(pkcs11_decrypt_update(hSession, pEncryptedData, ulEncryptedDataLen, pData, pDataLen)); } /** @@ -575,11 +554,8 @@ CK_RV C_DecryptUpdate */ CK_RV C_DecryptFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG_PTR pDataLen) { - ((void)hSession); - ((void)pData); - ((void)pDataLen); PKCS11_DEBUG("\r\n"); - PKCS11_DEBUG_RETURN(CKR_FUNCTION_NOT_SUPPORTED); + PKCS11_DEBUG_RETURN(pkcs11_decrypt_final(hSession, pData, pDataLen)); } /** @@ -835,13 +811,8 @@ CK_RV C_GenerateKey CK_OBJECT_HANDLE_PTR phKey ) { - ((void)hSession); - ((void)pMechanism); - ((void)pTemplate); - ((void)ulCount); - ((void)phKey); PKCS11_DEBUG("\r\n"); - PKCS11_DEBUG_RETURN(CKR_FUNCTION_NOT_SUPPORTED); + PKCS11_DEBUG_RETURN(pkcs11_key_generate(hSession, pMechanism, pTemplate, ulCount, phKey)); } /** diff --git a/lib/pkcs11/pkcs11_mech.c b/lib/pkcs11/pkcs11_mech.c index c3e05d6ec..6541a94e5 100644 --- a/lib/pkcs11/pkcs11_mech.c +++ b/lib/pkcs11/pkcs11_mech.c @@ -48,25 +48,25 @@ typedef struct _pcks11_mech_table_e static pcks11_mech_table_e pkcs11_mech_list_ecc508[] = { //CKM_DH_PKCS_KEY_PAIR_GEN, //CKM_DH_PKCS_DERIVE, - { CKM_SHA256, { 256, 256, CKF_HW | CKF_DIGEST } }, - { CKM_SHA256_HMAC, { 256, 256, CKF_HW | CKF_SIGN | CKF_VERIFY } }, - { CKM_SHA256_HMAC_GENERAL, { 256, 256, CKF_HW | CKF_SIGN | CKF_VERIFY } }, - { CKM_GENERIC_SECRET_KEY_GEN, { 0, 0, CKF_HW | CKF_GENERATE | CKF_GENERATE_KEY_PAIR } }, - { CKM_CONCATENATE_BASE_AND_KEY, { 0, 0, CKF_HW | CKF_DERIVE } }, - { CKM_CONCATENATE_BASE_AND_DATA, { 0, 0, CKF_HW | CKF_DERIVE } }, - { CKM_CONCATENATE_DATA_AND_BASE, { 0, 0, CKF_HW | CKF_DERIVE } }, - { CKM_XOR_BASE_AND_DATA, { 0, 0, CKF_HW | CKF_DERIVE } }, - { CKM_EXTRACT_KEY_FROM_KEY, { 0, 0, CKF_HW | CKF_DERIVE } }, - { CKM_SSL3_PRE_MASTER_KEY_GEN, { 0, 0, CKF_HW | CKF_GENERATE | CKF_GENERATE_KEY_PAIR } }, - { CKM_SSL3_MASTER_KEY_DERIVE, { 0, 0, CKF_HW | CKF_DERIVE } }, - { CKM_SSL3_KEY_AND_MAC_DERIVE, { 0, 0, CKF_HW | CKF_DERIVE } }, - { CKM_SSL3_MASTER_KEY_DERIVE_DH, { 0, 0, CKF_HW | CKF_DERIVE } }, - { CKM_TLS_PRE_MASTER_KEY_GEN, { 0, 0, CKF_HW | CKF_GENERATE | CKF_GENERATE_KEY_PAIR } }, - { CKM_TLS_MASTER_KEY_DERIVE, { 0, 0, CKF_HW | CKF_DERIVE } }, - { CKM_TLS_KEY_AND_MAC_DERIVE, { 0, 0, CKF_HW | CKF_DERIVE } }, - { CKM_TLS_MASTER_KEY_DERIVE_DH, { 0, 0, CKF_HW | CKF_DERIVE } }, - { CKM_TLS_PRF, { 0, 0, CKF_HW | CKF_DERIVE } }, - { CKM_SHA256_KEY_DERIVATION, { 256, 256, CKF_HW | CKF_DERIVE } }, + { CKM_SHA256, { 256, 256, CKF_HW | CKF_DIGEST } }, + { CKM_SHA256_HMAC, { 256, 256, CKF_HW | CKF_SIGN | CKF_VERIFY } }, + { CKM_SHA256_HMAC_GENERAL, { 256, 256, CKF_HW | CKF_SIGN | CKF_VERIFY } }, + { CKM_GENERIC_SECRET_KEY_GEN, { 0, 0, CKF_HW | CKF_GENERATE | CKF_GENERATE_KEY_PAIR } }, + { CKM_CONCATENATE_BASE_AND_KEY, { 0, 0, CKF_HW | CKF_DERIVE } }, + { CKM_CONCATENATE_BASE_AND_DATA, { 0, 0, CKF_HW | CKF_DERIVE } }, + { CKM_CONCATENATE_DATA_AND_BASE, { 0, 0, CKF_HW | CKF_DERIVE } }, + { CKM_XOR_BASE_AND_DATA, { 0, 0, CKF_HW | CKF_DERIVE } }, + { CKM_EXTRACT_KEY_FROM_KEY, { 0, 0, CKF_HW | CKF_DERIVE } }, + { CKM_SSL3_PRE_MASTER_KEY_GEN, { 0, 0, CKF_HW | CKF_GENERATE | CKF_GENERATE_KEY_PAIR } }, + { CKM_SSL3_MASTER_KEY_DERIVE, { 0, 0, CKF_HW | CKF_DERIVE } }, + { CKM_SSL3_KEY_AND_MAC_DERIVE, { 0, 0, CKF_HW | CKF_DERIVE } }, + { CKM_SSL3_MASTER_KEY_DERIVE_DH, { 0, 0, CKF_HW | CKF_DERIVE } }, + { CKM_TLS_PRE_MASTER_KEY_GEN, { 0, 0, CKF_HW | CKF_GENERATE | CKF_GENERATE_KEY_PAIR } }, + { CKM_TLS_MASTER_KEY_DERIVE, { 0, 0, CKF_HW | CKF_DERIVE } }, + { CKM_TLS_KEY_AND_MAC_DERIVE, { 0, 0, CKF_HW | CKF_DERIVE } }, + { CKM_TLS_MASTER_KEY_DERIVE_DH, { 0, 0, CKF_HW | CKF_DERIVE } }, + { CKM_TLS_PRF, { 0, 0, CKF_HW | CKF_DERIVE } }, + { CKM_SHA256_KEY_DERIVATION, { 256, 256, CKF_HW | CKF_DERIVE } }, //CKM_WTLS_PRE_MASTER_KEY_GEN, //CKM_WTLS_MASTER_KEY_DERIVE, //CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC, @@ -97,13 +97,13 @@ static pcks11_mech_table_e pkcs11_mech_list_ecc508[] = { //CKM_SEED_CBC_PAD, //CKM_SEED_ECB_ENCRYPT_DATA, //CKM_SEED_CBC_ENCRYPT_DATA, - { CKM_EC_KEY_PAIR_GEN, { 0, 0, CKF_HW | CKF_GENERATE | CKF_GENERATE_KEY_PAIR | PCKS11_MECH_ECC508_EC_CAPABILITY } }, - { CKM_ECDSA, { 256, 256, CKF_HW | CKF_SIGN | CKF_VERIFY | PCKS11_MECH_ECC508_EC_CAPABILITY } }, - { CKM_ECDSA_SHA256, { 256, 256, CKF_HW | CKF_SIGN | CKF_VERIFY | PCKS11_MECH_ECC508_EC_CAPABILITY } }, - { CKM_ECDH1_DERIVE, { 0, 0, CKF_HW | CKF_DERIVE | PCKS11_MECH_ECC508_EC_CAPABILITY } }, - { CKM_ECDH1_COFACTOR_DERIVE, { 0, 0, CKF_HW | CKF_DERIVE | PCKS11_MECH_ECC508_EC_CAPABILITY } }, - { CKM_ECMQV_DERIVE, { 0, 0, CKF_HW | CKF_DERIVE | PCKS11_MECH_ECC508_EC_CAPABILITY } }, - { CKM_ECDH_AES_KEY_WRAP, { 0, 0, CKF_HW | CKF_WRAP | CKF_UNWRAP | PCKS11_MECH_ECC508_EC_CAPABILITY } }, + { CKM_EC_KEY_PAIR_GEN, { 0, 0, CKF_HW | CKF_GENERATE | CKF_GENERATE_KEY_PAIR | PCKS11_MECH_ECC508_EC_CAPABILITY } }, + { CKM_ECDSA, { 256, 256, CKF_HW | CKF_SIGN | CKF_VERIFY | PCKS11_MECH_ECC508_EC_CAPABILITY } }, + { CKM_ECDSA_SHA256, { 256, 256, CKF_HW | CKF_SIGN | CKF_VERIFY | PCKS11_MECH_ECC508_EC_CAPABILITY } }, + { CKM_ECDH1_DERIVE, { 0, 0, CKF_HW | CKF_DERIVE | PCKS11_MECH_ECC508_EC_CAPABILITY } }, + { CKM_ECDH1_COFACTOR_DERIVE, { 0, 0, CKF_HW | CKF_DERIVE | PCKS11_MECH_ECC508_EC_CAPABILITY } }, + { CKM_ECMQV_DERIVE, { 0, 0, CKF_HW | CKF_DERIVE | PCKS11_MECH_ECC508_EC_CAPABILITY } }, + { CKM_ECDH_AES_KEY_WRAP, { 0, 0, CKF_HW | CKF_WRAP | CKF_UNWRAP | PCKS11_MECH_ECC508_EC_CAPABILITY } }, //CKM_FASTHASH, //CKM_AES_KEY_GEN, //CKM_AES_ECB, @@ -119,10 +119,10 @@ static pcks11_mech_table_e pkcs11_mech_list_ecc508[] = { //CKM_AES_CMAC_GENERAL, //CKM_AES_XCBC_MAC, //CKM_AES_XCBC_MAC_96, - //CKM_AES_GMAC, + //{CKM_AES_GMAC, //CKM_AES_ECB_ENCRYPT_DATA, //CKM_AES_CBC_ENCRYPT_DATA, - { CKM_DH_PKCS_PARAMETER_GEN, { 0, 0, CKF_HW | CKF_GENERATE | CKF_GENERATE_KEY_PAIR } } + { CKM_DH_PKCS_PARAMETER_GEN, { 0, 0, CKF_HW | CKF_GENERATE | CKF_GENERATE_KEY_PAIR } } //CKM_AES_OFB, //CKM_AES_CFB64, //CKM_AES_CFB8, @@ -136,9 +136,9 @@ static pcks11_mech_table_e pkcs11_mech_list_ecc508[] = { static pcks11_mech_table_e pkcs11_mech_list_ecc608[] = { //CKM_DH_PKCS_KEY_PAIR_GEN, //CKM_DH_PKCS_DERIVE, - { CKM_SHA256, { 256, 256, CKF_HW | CKF_DIGEST } }, - //{ CKM_SHA256_HMAC,{ 256, 256, CKF_HW | CKF_SIGN | CKF_VERIFY } }, - //{ CKM_SHA256_HMAC_GENERAL,{ 256, 256, CKF_HW | CKF_SIGN | CKF_VERIFY } }, + { CKM_SHA256, { 256, 256, CKF_HW | CKF_DIGEST } }, + { CKM_SHA256_HMAC, { 256, 256, CKF_HW | CKF_SIGN | CKF_VERIFY } }, + { CKM_SHA256_HMAC_GENERAL, { 256, 256, CKF_HW | CKF_SIGN | CKF_VERIFY } }, //{ CKM_GENERIC_SECRET_KEY_GEN,{ 0, 0, CKF_HW | CKF_GENERATE | CKF_GENERATE_KEY_PAIR } }, //{ CKM_CONCATENATE_BASE_AND_KEY,{ 0, 0, CKF_HW | CKF_DERIVE } }, //{ CKM_CONCATENATE_BASE_AND_DATA,{ 0, 0, CKF_HW | CKF_DERIVE } }, @@ -185,8 +185,8 @@ static pcks11_mech_table_e pkcs11_mech_list_ecc608[] = { //CKM_SEED_CBC_PAD, //CKM_SEED_ECB_ENCRYPT_DATA, //CKM_SEED_CBC_ENCRYPT_DATA, - { CKM_EC_KEY_PAIR_GEN, { 256, 256, CKF_HW | CKF_GENERATE | CKF_GENERATE_KEY_PAIR | PCKS11_MECH_ECC508_EC_CAPABILITY } }, - { CKM_ECDSA, { 256, 256, CKF_HW | CKF_SIGN | CKF_VERIFY | PCKS11_MECH_ECC508_EC_CAPABILITY } }, + { CKM_EC_KEY_PAIR_GEN, { 256, 256, CKF_HW | CKF_GENERATE | CKF_GENERATE_KEY_PAIR | PCKS11_MECH_ECC508_EC_CAPABILITY } }, + { CKM_ECDSA, { 256, 256, CKF_HW | CKF_SIGN | CKF_VERIFY | PCKS11_MECH_ECC508_EC_CAPABILITY } }, //{ CKM_ECDSA_SHA256,{ 256, 256, CKF_HW | CKF_SIGN | CKF_VERIFY | PCKS11_MECH_ECC508_EC_CAPABILITY } }, //{ CKM_ECDH1_DERIVE,{ 0, 0, CKF_HW | CKF_DERIVE | PCKS11_MECH_ECC508_EC_CAPABILITY } }, //{ CKM_ECDH1_COFACTOR_DERIVE,{ 0, 0, CKF_HW | CKF_DERIVE | PCKS11_MECH_ECC508_EC_CAPABILITY } }, @@ -194,22 +194,22 @@ static pcks11_mech_table_e pkcs11_mech_list_ecc608[] = { //{ CKM_ECDH_AES_KEY_WRAP,{ 0, 0, CKF_HW | CKF_WRAP | CKF_UNWRAP | PCKS11_MECH_ECC508_EC_CAPABILITY } }, //CKM_FASTHASH, //CKM_AES_KEY_GEN, - //CKM_AES_ECB, - //CKM_AES_CBC, - //CKM_AES_MAC, - //CKM_AES_MAC_GENERAL, + { CKM_AES_ECB, { 128, 128, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT } }, + { CKM_AES_CBC, { 128, 128, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT } }, + //{CKM_AES_MAC, { 128, 128, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT} }, + //{CKM_AES_MAC_GENERAL, { 128, 128, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT} }, //CKM_AES_CBC_PAD, - //CKM_AES_CTR, - //CKM_AES_GCM, - //CKM_AES_CCM, + { CKM_AES_CTR, { 128, 128, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT } }, + { CKM_AES_GCM, { 128, 128, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT } }, + { CKM_AES_CCM, { 128, 128, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT } }, //CKM_AES_CTS, - //CKM_AES_CMAC, - //CKM_AES_CMAC_GENERAL, + { CKM_AES_CMAC, { 128, 128, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT } }, + { CKM_AES_CMAC_GENERAL, { 128, 128, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT } }, //CKM_AES_XCBC_MAC, //CKM_AES_XCBC_MAC_96, - //CKM_AES_GMAC, - //CKM_AES_ECB_ENCRYPT_DATA, - //CKM_AES_CBC_ENCRYPT_DATA, + //{CKM_AES_GMAC, + { CKM_AES_ECB_ENCRYPT_DATA, { 128, 128, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT } }, + { CKM_AES_CBC_ENCRYPT_DATA, { 128, 128, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT } }, //{ CKM_DH_PKCS_PARAMETER_GEN,{ 0, 0, CKF_HW | CKF_GENERATE | CKF_GENERATE_KEY_PAIR } } //CKM_AES_OFB, //CKM_AES_CFB64, diff --git a/lib/pkcs11/pkcs11_object.c b/lib/pkcs11/pkcs11_object.c index 12cc361ea..44dd068b2 100644 --- a/lib/pkcs11/pkcs11_object.c +++ b/lib/pkcs11/pkcs11_object.c @@ -68,16 +68,16 @@ static CK_OBJECT_HANDLE pkcs11_object_alloc_handle(void) */ const pkcs11_attrib_model pkcs11_object_monotonic_attributes[] = { /** Object Class - CK_OBJECT_CLASS */ - { CKA_CLASS, pkcs11_object_get_class }, + { CKA_CLASS, pkcs11_object_get_class }, /** Hardware Feature Type - CK_HW_FEATURE_TYPE */ - { CKA_HW_FEATURE_TYPE, pkcs11_object_get_type }, + { CKA_HW_FEATURE_TYPE, pkcs11_object_get_type }, /** Counter will reset to a previously returned value if the token is initialized using C_InitToken. */ - { CKA_RESET_ON_INIT, pkcs11_attrib_false }, + { CKA_RESET_ON_INIT, pkcs11_attrib_false }, /** Counter has been reset at least once at some point in time. */ - { CKA_HAS_RESET, pkcs11_attrib_false }, + { CKA_HAS_RESET, pkcs11_attrib_false }, /** Current value of the monotonic counter. Big endian order. */ - { CKA_VALUE, NULL_PTR }, + { CKA_VALUE, NULL_PTR }, }; const CK_ULONG pkcs11_object_monotonic_attributes_count = PKCS11_UTIL_ARRAY_SIZE(pkcs11_object_monotonic_attributes); @@ -179,6 +179,7 @@ CK_RV pkcs11_object_free(pkcs11_object_ptr pObject) if (pObject) { +#if ATCA_CA_SUPPORT if (pObject->data) { if (pObject->flags & PKCS11_OBJECT_FLAG_SENSITIVE) @@ -192,6 +193,7 @@ CK_RV pkcs11_object_free(pkcs11_object_ptr pObject) } #endif } +#endif (void)pkcs11_util_memset(pObject, sizeof(pkcs11_object), 0, sizeof(pkcs11_object) ); @@ -354,7 +356,7 @@ CK_RV pkcs11_object_get_size(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObjec CK_RV pkcs11_object_find(pkcs11_object_ptr * ppObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) { - int i; + CK_ULONG i; CK_ATTRIBUTE_PTR pName = NULL; CK_OBJECT_CLASS class = CKO_PRIVATE_KEY; /* Unless specified assume private key object */ @@ -454,13 +456,17 @@ CK_RV pkcs11_object_create } } - rv = pkcs11_object_find(&pObject, pTemplate, ulCount); - - if (rv) + if (pLabel && pClass) { - return rv; + if (CKR_OK != (rv = pkcs11_object_find(&pObject, pTemplate, ulCount))) + { + return rv; + } } - + { + return CKR_ARGUMENTS_BAD; + } + if (!pObject) { /* Allocate a new object */ @@ -483,115 +489,170 @@ CK_RV pkcs11_object_create if (CKR_OK == (rv = pkcs11_config_key(pLibCtx, pSession->slot, pObject, pLabel))) { rv = pkcs11_key_write(pSession, pObject, pData); - } - break; - case CKO_PRIVATE_KEY: - pObject->class_id = CKO_PRIVATE_KEY; - if (CKR_OK == (rv = pkcs11_config_key(pLibCtx, pSession->slot, pObject, pLabel))) - { - rv = pkcs11_key_write(pSession, pObject, pData); - } - break; - default: - break; - } - if (CKR_OK == rv) - { - rv = pkcs11_object_get_handle(pObject, phObject); - } - } + if (rv) + { + (void)pkcs11_config_remove_object ((pLibCtx, pSession->slot, pObject); + } + } + break; + case CKO_PRIVATE_KEY: + pObject->class_id = CKO_PRIVATE_KEY; + if (CKR_OK == (rv = pkcs11_config_key(pLibCtx, pSession->slot, pObject, pLabel))) + { + rv = pkcs11_key_write(pSession, pObject, pData); + if (rv) + { + (void)pkcs11_config_remove_object(pLibCtx, pSession->slot, pObject); + } + } + break; + default: + break; + } + if (CKR_OK == rv) + { + rv = pkcs11_object_get_handle(pObject, phObject); + } + else + { + if (pObject) + { + (void)pkcs11_object_free(pObject); + } + } + } - return rv; -} + return rv; + } /** * \brief Destroy the specified object */ -CK_RV pkcs11_object_destroy(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject) -{ - pkcs11_object_ptr pObject; - CK_RV rv; - pkcs11_lib_ctx_ptr pLibCtx = NULL; - pkcs11_session_ctx_ptr pSession = NULL; - - rv = pkcs11_init_check(&pLibCtx, FALSE); - if (rv) - { - return rv; - } - - rv = pkcs11_session_check(&pSession, hSession); - if (rv) - { - return rv; - } - - rv = pkcs11_object_check(&pObject, hObject); - if (rv) - { - return rv; - } - - if (pObject->flags & PKCS11_OBJECT_FLAG_DESTROYABLE) - { + CK_RV pkcs11_object_destroy(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject) + { + pkcs11_object_ptr pObject; + CK_RV rv; + pkcs11_lib_ctx_ptr pLibCtx = NULL; + pkcs11_session_ctx_ptr pSession = NULL; + + rv = pkcs11_init_check(&pLibCtx, FALSE); + if (rv) + { + return rv; + } + + rv = pkcs11_session_check(&pSession, hSession); + if (rv) + { + return rv; + } + + rv = pkcs11_object_check(&pObject, hObject); + if (rv) + { + return rv; + } + + if (pObject->flags & PKCS11_OBJECT_FLAG_DESTROYABLE) + { #if !PKCS11_USE_STATIC_CONFIG - pkcs11_config_remove_object(pLibCtx, pSession->slot, pObject); + pkcs11_config_remove_object(pLibCtx, pSession->slot, pObject); #endif - return pkcs11_object_free(pObject); - } - else - { - return CKR_ACTION_PROHIBITED; - } -} + return pkcs11_object_free(pObject); + } + else + { + return CKR_ACTION_PROHIBITED; + } + } /* Interal function to clean up resources */ -CK_RV pkcs11_object_deinit(pkcs11_lib_ctx_ptr pContext) -{ - CK_RV rv = CKR_OK; - int i; - - for (i = 0; i < PKCS11_MAX_OBJECTS_ALLOWED; i++) - { - pkcs11_object_ptr pObj = pkcs11_object_cache[i].object; - if (pObj) - { - CK_RV tmp = pkcs11_object_free(pObj); - if (!rv) - { - rv = tmp; - } - } - } - return rv; -} + CK_RV pkcs11_object_deinit(pkcs11_lib_ctx_ptr pContext) + { + CK_RV rv = CKR_OK; + int i; + + for (i = 0; i < PKCS11_MAX_OBJECTS_ALLOWED; i++) + { + pkcs11_object_ptr pObj = pkcs11_object_cache[i].object; + if (pObj) + { + CK_RV tmp = pkcs11_object_free(pObj); + if (!rv) + { + rv = tmp; + } + } + } + return rv; + } #if ATCA_TA_SUPPORT -CK_RV pkcs11_object_load_handle_info(pkcs11_lib_ctx_ptr pContext) -{ - CK_RV rv = CKR_OK; - uint8_t handle_info[TA_HANDLE_INFO_SIZE]; + CK_RV pkcs11_object_load_handle_info(pkcs11_lib_ctx_ptr pContext) + { + CK_RV rv = CKR_OK; + uint8_t handle_info[TA_HANDLE_INFO_SIZE]; + + for (int i = 0; i < PKCS11_MAX_OBJECTS_ALLOWED; i++) + { + pkcs11_object_ptr pObj = pkcs11_object_cache[i].object; + if (pObj) + { + pObj->flags |= PKCS11_OBJECT_FLAG_TA_TYPE; + if (ATCA_SUCCESS == talib_info_get_handle_info(atcab_get_device(), pObj->slot, handle_info)) + { + memcpy(&pObj->handle_info, handle_info, sizeof(ta_element_attributes_t)); + } + else + { + memset(&pObj->handle_info, 0, sizeof(ta_element_attributes_t)); + } + + } + } + return rv; + } +#endif - for (int i = 0; i < PKCS11_MAX_OBJECTS_ALLOWED; i++) - { - pkcs11_object_ptr pObj = pkcs11_object_cache[i].object; - if (pObj) - { - pObj->flags |= PKCS11_OBJECT_FLAG_TA_TYPE; - if (ATCA_SUCCESS == talib_info_get_handle_info(atcab_get_device(), pObj->slot, handle_info)) - { - memcpy(&pObj->handle_info, handle_info, sizeof(ta_element_attributes_t)); - } - else - { - memset(&pObj->handle_info, 0, sizeof(ta_element_attributes_t)); - } - } - } - return rv; -} +/** \brief Checks the attributes of the underlying cryptographic asset to + determine if it is a private key - this changes the way the associated + public key is referenced */ + CK_RV pkcs11_object_is_private(pkcs11_object_ptr pObject, CK_BBOOL * is_private) + { + CK_RV rv = CKR_ARGUMENTS_BAD; + if (pObject && is_private) + { + ATCADeviceType dev_type = atcab_get_device_type(); + + *is_private = false; + rv = CKR_GENERAL_ERROR; + + if (atcab_is_ca_device(dev_type)) + { +#if ATCA_CA_SUPPORT + atecc508a_config_t* cfg_ptr = (atecc508a_config_t*)pObject->config; + + if (cfg_ptr) + { + *is_private = (cfg_ptr->KeyConfig[pObject->slot] & ATCA_KEY_CONFIG_PRIVATE_MASK) ? true : false; + rv = CKR_OK; + } #endif + } + else if (atcab_is_ta_device(dev_type)) + { +#if ATCA_TA_SUPPORT + *is_private = (TA_CLASS_PRIVATE_KEY == (pObject->handle_info.element_CKA & 0xF)); + rv = CKR_OK; +#endif + } + + } + + return rv; + } + /** @} */ diff --git a/lib/pkcs11/pkcs11_object.h b/lib/pkcs11/pkcs11_object.h index 8da5feaa4..4433fd779 100644 --- a/lib/pkcs11/pkcs11_object.h +++ b/lib/pkcs11/pkcs11_object.h @@ -85,6 +85,7 @@ CK_RV pkcs11_object_alloc(pkcs11_object_ptr * ppObject); CK_RV pkcs11_object_free(pkcs11_object_ptr pObject); CK_RV pkcs11_object_check(pkcs11_object_ptr * ppObject, CK_OBJECT_HANDLE handle); CK_RV pkcs11_object_find(pkcs11_object_ptr * ppObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount); +CK_RV pkcs11_object_is_private(pkcs11_object_ptr pObject, CK_BBOOL* is_private); CK_RV pkcs11_object_get_class(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute); CK_RV pkcs11_object_get_name(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute); diff --git a/lib/pkcs11/pkcs11_session.c b/lib/pkcs11/pkcs11_session.c index cbbbf6cc0..05648f281 100644 --- a/lib/pkcs11/pkcs11_session.c +++ b/lib/pkcs11/pkcs11_session.c @@ -26,6 +26,7 @@ */ #include "cryptoauthlib.h" +#include "crypto/atca_crypto_sw_rand.h" #include "host/atca_host.h" #include "pkcs11_config.h" @@ -234,6 +235,7 @@ CK_RV pkcs11_session_open( /* Initialize the session */ session_ctx->slot = slot_ctx; session_ctx->initialized = TRUE; + session_ctx->active_mech = CKM_VENDOR_DEFINED; /* Assign the session handle */ session_ctx->handle = (CK_SESSION_HANDLE)session_ctx; @@ -365,8 +367,10 @@ CK_RV pkcs11_session_login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK { pkcs11_lib_ctx_ptr pLibCtx = pkcs11_get_context(); pkcs11_session_ctx_ptr session_ctx = pkcs11_get_session_context(hSession); - uint8_t sn[ATCA_SERIAL_NUM_SIZE]; + bool is_ca_device = atcab_is_ca_device(atcab_get_device_type()); + uint16_t key_len = is_ca_device ? 32 : 16; CK_RV rv; + ATCA_STATUS status; if (!pLibCtx || !pLibCtx->initialized) { @@ -375,6 +379,7 @@ CK_RV pkcs11_session_login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK if (!pPin || !ulPinLen) { + PKCS11_DEBUG("pin: %p, pin-len: %d\n", pPin, ulPinLen); return CKR_ARGUMENTS_BAD; } @@ -388,29 +393,60 @@ CK_RV pkcs11_session_login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK return CKR_SESSION_CLOSED; } - if (64 != ulPinLen) + if (session_ctx->slot->logged_in) + { + return CKR_USER_ALREADY_LOGGED_IN; + } + + if (CKR_OK == (rv = pkcs11_lock_context(pLibCtx))) { - if (CKR_OK == (rv = pkcs11_lock_context(pLibCtx))) +#ifndef PKCS11_PIN_KDF_ALWAYS + if (2 * key_len == ulPinLen) { - rv = pkcs11_util_convert_rv(atcab_read_serial_number(sn)); - (void)pkcs11_unlock_context(pLibCtx); + rv = pkcs11_token_convert_pin_to_key(pPin, ulPinLen, NULL, 0, session_ctx->slot->read_key, key_len); } + else +#endif + { + uint8_t sn[ATCA_SERIAL_NUM_SIZE]; - if (CKR_OK == rv) + if (CKR_OK == (rv = pkcs11_util_convert_rv(atcab_read_serial_number(sn)))) + { + rv = pkcs11_token_convert_pin_to_key(pPin, ulPinLen, sn, (CK_LONG)sizeof(sn), session_ctx->slot->read_key, key_len); + } + } + +#if ATCA_TA_SUPPORT + if (CKR_OK == rv && atcab_is_ta_device(atcab_get_device_type())) { - rv = pkcs11_token_convert_pin_to_key(pPin, ulPinLen, sn, (CK_LONG)sizeof(sn), - session_ctx->read_key, (CK_LONG)sizeof(session_ctx->read_key)); + uint8_t auth_i_nonce[16]; + uint8_t auth_r_nonce[16]; + + (void)atcac_sw_random(auth_r_nonce, sizeof(auth_r_nonce)); + + status = talib_auth_generate_nonce(_gDevice, 0x4100, + TA_AUTH_GENERATE_OPT_NONCE_SRC_MASK | TA_AUTH_GENERATE_OPT_RANDOM_MASK, auth_i_nonce); + + if (CKR_OK == (rv = pkcs11_util_convert_rv(status))) + { + status = talib_auth_startup(atcab_get_device(), session_ctx->slot->user_pin_handle, + TA_AUTH_ALG_ID_GCM, 0x1FFF, 16, session_ctx->slot->read_key, auth_i_nonce, auth_r_nonce); + rv = pkcs11_util_convert_rv(status); + } + + if (CKR_OK != rv) + { + (void)talib_auth_terminate(atcab_get_device()); + } } - } - else - { - rv = pkcs11_token_convert_pin_to_key(pPin, ulPinLen, NULL, 0, session_ctx->read_key, - (CK_LONG)sizeof(session_ctx->read_key)); +#endif + + (void)pkcs11_unlock_context(pLibCtx); } if (CKR_OK == rv) { - session_ctx->logged_in = TRUE; + session_ctx->slot->logged_in = TRUE; } return rv; @@ -436,10 +472,17 @@ CK_RV pkcs11_session_logout(CK_SESSION_HANDLE hSession) return CKR_SESSION_CLOSED; } +#if ATCA_TA_SUPPORT + if (session_ctx->slot->logged_in && atcab_is_ta_device(atcab_get_device_type())) + { + (void)talib_auth_terminate(atcab_get_device()); + } +#endif + /* Wipe the io protection secret */ - (void)pkcs11_util_memset(session_ctx->read_key, sizeof(session_ctx->read_key), 0, sizeof(session_ctx->read_key)); + (void)pkcs11_util_memset(session_ctx->slot->read_key, sizeof(session_ctx->slot->read_key), 0, sizeof(session_ctx->slot->read_key)); - session_ctx->logged_in = FALSE; + session_ctx->slot->logged_in = FALSE; return CKR_OK; } diff --git a/lib/pkcs11/pkcs11_session.h b/lib/pkcs11/pkcs11_session.h index 3af6ab672..cd0082168 100644 --- a/lib/pkcs11/pkcs11_session.h +++ b/lib/pkcs11/pkcs11_session.h @@ -35,21 +35,40 @@ extern "C" { #endif +/* Some mechanism require the context to be initialized first and it is done + in a previous command than the target operation */ +typedef union _pkcs11_session_mech_ctx +{ + struct + { + atca_hmac_sha256_ctx_t context; + } hmac; + struct + { + atca_aes_cmac_ctx_t context; + } cmac; + struct + { + atca_aes_gcm_ctx_t context; + CK_BYTE tag_len; + } gcm; +} pkcs11_session_mech_ctx, *pkcs11_session_mech_ctx_ptr; + /** Session Context */ typedef struct _pkcs11_session_ctx { - CK_BBOOL initialized; - pkcs11_slot_ctx_ptr slot; - CK_SESSION_HANDLE handle; - CK_STATE state; - CK_ULONG error; - CK_ATTRIBUTE_PTR attrib_list; - CK_ULONG attrib_count; - CK_ULONG object_index; - CK_ULONG object_count; - CK_OBJECT_HANDLE active_object; - CK_BBOOL logged_in; - CK_BYTE read_key[32]; /**< Accepted through C_Login as the user pin */ + CK_BBOOL initialized; + pkcs11_slot_ctx_ptr slot; + CK_SESSION_HANDLE handle; + CK_STATE state; + CK_ULONG error; + CK_ATTRIBUTE_PTR attrib_list; + CK_ULONG attrib_count; + CK_ULONG object_index; + CK_ULONG object_count; + CK_OBJECT_HANDLE active_object; + CK_MECHANISM_TYPE active_mech; + pkcs11_session_mech_ctx active_mech_data; } pkcs11_session_ctx, *pkcs11_session_ctx_ptr; #ifdef __cplusplus diff --git a/lib/pkcs11/pkcs11_signature.c b/lib/pkcs11/pkcs11_signature.c index 66cc26fee..cf94f0f8d 100644 --- a/lib/pkcs11/pkcs11_signature.c +++ b/lib/pkcs11/pkcs11_signature.c @@ -72,9 +72,17 @@ CK_RV pkcs11_signature_sign_init(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pM return rv; } - pSession->active_object = hKey; + if (CKM_VENDOR_DEFINED == pSession->active_mech) + { + pSession->active_object = hKey; + pSession->active_mech = pMechanism->mechanism; + } + else + { + rv = CKR_OPERATION_ACTIVE; + } - return CKR_OK; + return rv; } /** @@ -117,15 +125,29 @@ CK_RV pkcs11_signature_sign(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_UL { return rv; } - status = atcab_sign(pKey->slot, pData, pSignature); + + switch (pSession->active_mech) + { + case CKM_SHA256_HMAC: + status = atcab_sha_hmac(pData, ulDataLen, pKey->slot, pSignature, SHA_MODE_TARGET_OUT_ONLY); + *pulSignatureLen = ATCA_SHA256_DIGEST_SIZE; + break; + case CKM_ECDSA: + status = atcab_sign(pKey->slot, pData, pSignature); + *pulSignatureLen = ATCA_SIG_SIZE; + break; + default: + status = ATCA_GEN_FAIL; + break; + } + pSession->active_mech = CKM_VENDOR_DEFINED; + (void)pkcs11_unlock_context(pLibCtx); - if (status) + if (CKR_OK == rv && ATCA_SUCCESS != status) { - PKCS11_DEBUG("atcab_sign: %02X\n", status); - return CKR_FUNCTION_FAILED; + return pkcs11_util_convert_rv(status); } } - *pulSignatureLen = ATCA_SIG_SIZE; } else { @@ -191,9 +213,18 @@ CK_RV pkcs11_signature_verify_init(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR return rv; } - pSession->active_object = hKey; + if (CKM_VENDOR_DEFINED == pSession->active_mech) + { + pSession->active_object = hKey; + pSession->active_mech = pMechanism->mechanism; + rv = CKR_OK; + } + else + { + rv = CKR_OPERATION_ACTIVE; + } - return CKR_OK; + return rv; } /** @@ -204,9 +235,7 @@ CK_RV pkcs11_signature_verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ pkcs11_lib_ctx_ptr pLibCtx = NULL; pkcs11_session_ctx_ptr pSession; pkcs11_object_ptr pKey; - atecc508a_config_t * pConfig; - ATCA_STATUS status; - bool verified = FALSE; + CK_BBOOL is_private; CK_RV rv; rv = pkcs11_init_check(&pLibCtx, FALSE); @@ -228,7 +257,7 @@ CK_RV pkcs11_signature_verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ } /* Check parameters */ - if (!pData || ulDataLen != ATCA_SHA_DIGEST_SIZE || !pSignature || ulSignatureLen != VERIFY_256_SIGNATURE_SIZE) + if (!pData || ulDataLen != ATCA_SHA256_DIGEST_SIZE || !pSignature || ulSignatureLen != ATCA_ECCP256_SIG_SIZE) { return CKR_ARGUMENTS_BAD; } @@ -244,24 +273,50 @@ CK_RV pkcs11_signature_verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ return rv; } - if (ATCA_KEY_CONFIG_PRIVATE_MASK & pConfig->KeyConfig[pKey->slot]) + switch (pSession->active_mech) { - /* Device can't verify against a private key so ask the device for - the public key first then perform an external verify */ - uint8_t pub_key[ATCA_PUB_KEY_SIZE]; - - status = atcab_get_pubkey(pKey->slot, pub_key); - if (ATCA_SUCCESS == status) + case CKM_SHA256_HMAC: + { + uint8_t buf[ATCA_SHA256_DIGEST_SIZE]; + if (ATCA_SUCCESS == (status = atcab_sha_hmac(pData, ulDataLen, pKey->slot, buf, SHA_MODE_TARGET_OUT_ONLY))) { - status = atcab_verify_extern(pData, pSignature, pub_key, &verified); + if (!memcmp(pSignature, buf, ATCA_SHA256_DIGEST_SIZE)) + { + verified = TRUE; + } } } - else - { - /* Assume Public Key has been stored properly and verify against - whatever is stored */ - status = atcab_verify_stored(pData, pSignature, pKey->slot, &verified); + break; + case CKM_ECDSA: + if (CKR_OK == (rv = pkcs11_object_is_private(pKey, &is_private))) + { + ATCA_STATUS status; + bool verified = FALSE; + + if (is_private) + { + /* Device can't verify against a private key so ask the device for + the public key first then perform an external verify */ + uint8_t pub_key[ATCA_ECCP256_PUBKEY_SIZE]; + + if (ATCA_SUCCESS == (status = atcab_get_pubkey(pKey->slot, pub_key))) + { + status = atcab_verify_extern(pData, pSignature, pub_key, &verified); + } + } + else + { + /* Assume Public Key has been stored properly and verify against + whatever is stored */ + status = atcab_verify_stored(pData, pSignature, pKey->slot, &verified); + } + } + break; + default: + status = ATCA_GEN_FAIL; + break; } + pSession->active_mech = CKM_VENDOR_DEFINED; (void)pkcs11_unlock_context(pLibCtx); diff --git a/lib/pkcs11/pkcs11_slot.c b/lib/pkcs11/pkcs11_slot.c index 015db7144..79620a724 100644 --- a/lib/pkcs11/pkcs11_slot.c +++ b/lib/pkcs11/pkcs11_slot.c @@ -220,15 +220,21 @@ CK_RV pkcs11_slot_init(CK_SLOT_ID slotID) { if (atcab_is_ca_device(ifacecfg->devtype)) { +#if ATCA_CA_SUPPORT /* Only the classic cryptoauth devices require the configuration to be loaded into memory */ status = atcab_read_config_zone((uint8_t*)&slot_ctx->cfg_zone); +#else + status = ATCA_GEN_FAIL; +#endif } else { #if ATCA_TA_SUPPORT /* Iterate through all objects and attach handle info */ status = pkcs11_object_load_handle_info(lib_ctx); +#else + status = ATCA_GEN_FAIL; #endif } } diff --git a/lib/pkcs11/pkcs11_slot.h b/lib/pkcs11/pkcs11_slot.h index 877c4f948..5069840e2 100644 --- a/lib/pkcs11/pkcs11_slot.h +++ b/lib/pkcs11/pkcs11_slot.h @@ -53,6 +53,8 @@ typedef struct _pkcs11_slot_ctx #ifndef PKCS11_LABEL_IS_SERNUM CK_UTF8CHAR label[PKCS11_MAX_LABEL_SIZE + 1]; #endif + CK_BBOOL logged_in; + CK_BYTE read_key[32]; /**< Accepted through C_Login as the user pin */ } pkcs11_slot_ctx, *pkcs11_slot_ctx_ptr; #ifdef __cplusplus diff --git a/lib/pkcs11/pkcs11_token.c b/lib/pkcs11/pkcs11_token.c index 3327907a5..e96e88928 100644 --- a/lib/pkcs11/pkcs11_token.c +++ b/lib/pkcs11/pkcs11_token.c @@ -38,7 +38,9 @@ #include "pkcs11_session.h" -#include +#ifndef ATCA_SERIAL_NUM_SIZE +#define ATCA_SERIAL_NUM_SIZE (9) +#endif /** * \defgroup pkcs11 Token Management (pkcs11_) @@ -125,7 +127,7 @@ CK_RV pkcs11_token_init(CK_SLOT_ID slotID, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinL { #if PKCS11_TOKEN_INIT_SUPPORT CK_RV rv; - uint8_t buf[32] = {0}; + uint8_t buf[32]; uint8_t * pConfig = NULL; bool lock = false; pkcs11_lib_ctx_ptr pLibCtx; @@ -150,7 +152,7 @@ CK_RV pkcs11_token_init(CK_SLOT_ID slotID, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinL if (CKR_OK == rv) { /* Check the config zone lock status */ - rv = atcab_is_locked(LOCK_ZONE_CONFIG, &lock); + rv = pkcs11_util_convert_rv(atcab_is_config_locked(&lock)); } if (atcab_is_ca_device(pSlotCtx->interface_config.devtype)) @@ -207,10 +209,9 @@ CK_RV pkcs11_token_init(CK_SLOT_ID slotID, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinL if (ATCA_SUCCESS == rv) { /* Check data zone lock */ - rv = atcab_is_locked(LOCK_ZONE_DATA, &lock); + rv = pkcs11_util_convert_rv(atcab_is_data_locked(&lock)); } - if (!lock && ATCA_SUCCESS == rv) { size_t buflen = sizeof(buf); @@ -242,7 +243,11 @@ CK_RV pkcs11_token_init(CK_SLOT_ID slotID, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinL { if (64 != ulPinLen) { + if (CKR_OK == (rv = pkcs11_lock_context(pLibCtx))) + { rv = pkcs11_util_convert_rv(atcab_read_serial_number(buf)); + (void)pkcs11_unlock_context(pLibCtx); + } if (CKR_OK == rv) { @@ -310,6 +315,7 @@ CK_RV pkcs11_token_get_access_type(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttrib { if (atcab_is_ca_device(atcab_get_device_type())) { +#if ATCA_CA_SUPPORT atecc508a_config_t * pConfig = (atecc508a_config_t*)obj_ptr->config; if (ATCA_KEY_CONFIG_PRIVATE_MASK & pConfig->KeyConfig[obj_ptr->slot]) @@ -320,6 +326,7 @@ CK_RV pkcs11_token_get_access_type(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttrib { return pkcs11_attrib_false(pObject, pAttribute); } +#endif } else { @@ -346,6 +353,7 @@ CK_RV pkcs11_token_get_writable(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute if (obj_ptr) { +#if ATCA_CA_SUPPORT atecc508a_config_t * pConfig = (atecc508a_config_t*)obj_ptr->config; if ((ATCA_KEY_CONFIG_PRIVATE_MASK & pConfig->KeyConfig[obj_ptr->slot]) || @@ -357,6 +365,7 @@ CK_RV pkcs11_token_get_writable(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute { return pkcs11_attrib_true(pObject, pAttribute); } +#endif } return CKR_ARGUMENTS_BAD; @@ -459,7 +468,7 @@ CK_RV pkcs11_token_get_info(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) } /* Check if the device locks are set */ - if (ATCA_SUCCESS == atcab_is_locked(LOCK_ZONE_DATA, &lock)) + if (ATCA_SUCCESS == atcab_is_data_locked(&lock)) { if (lock) { @@ -479,6 +488,7 @@ CK_RV pkcs11_token_get_info(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) PKCS11_DEBUG("Pin Slot Locked\r\n"); } } + pInfo->flags |= CKF_LOGIN_REQUIRED; } if (slot_ctx->so_pin_handle != 0xFFFF) @@ -576,14 +586,27 @@ CK_RV pkcs11_token_convert_pin_to_key( ) { ATCA_STATUS status = ATCA_SUCCESS; + bool is_ca_device = atcab_is_ca_device(atcab_get_device_type()); + uint16_t key_len = is_ca_device ? 32 : 16; - if (!pPin || !ulPinLen || !pKey || 32 > ulKeyLen) + if (!pPin || !ulPinLen || !pKey) { return CKR_ARGUMENTS_BAD; } - if (64 != ulPinLen) +#ifndef PKCS11_PIN_KDF_ALWAYS + if (2 * key_len == ulPinLen) + { + size_t out_len = ulKeyLen; + status = atcab_hex2bin((char*)pPin, ulPinLen, pKey, &out_len); + ulKeyLen = (CK_ULONG)out_len; + } + else +#endif { +#ifdef PKCS11_PIN_PBKDF2_EN + status = atcac_pbkdf2_sha256(PKCS11_PIN_PBKDF2_ITERATIONS, pPin, ulPinLen, pSalt, ulSaltLen, pKey, ulKeyLen); +#else atcac_sha2_256_ctx ctx; status = atcac_sw_sha2_256_init(&ctx); @@ -601,18 +624,12 @@ CK_RV pkcs11_token_convert_pin_to_key( { status = atcac_sw_sha2_256_finish(&ctx, pKey); } - } - else - { - size_t out_len = ulKeyLen; - status = atcab_hex2bin((char*)pPin, ulPinLen, pKey, &out_len); - ulKeyLen = (CK_ULONG)out_len; +#endif } return pkcs11_util_convert_rv(status); } -#include CK_RV pkcs11_token_set_pin(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pOldPin, CK_ULONG ulOldLen, CK_UTF8CHAR_PTR pNewPin, CK_ULONG ulNewLen) { @@ -621,6 +638,8 @@ CK_RV pkcs11_token_set_pin(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pOldPin, uint16_t pin_slot; uint8_t buf[32]; CK_RV rv; + bool is_ca_device = atcab_is_ca_device(atcab_get_device_type()); + uint16_t key_len = is_ca_device ? 32 : 16; rv = pkcs11_init_check(&pLibCtx, FALSE); if (rv) @@ -639,30 +658,42 @@ CK_RV pkcs11_token_set_pin(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pOldPin, return rv; } - if (64 != ulNewLen) + if (CKR_OK == (rv = pkcs11_lock_context(pLibCtx))) { - if (CKR_OK == (rv = pkcs11_lock_context(pLibCtx))) +#ifndef PKCS11_PIN_KDF_ALWAYS + if (2 * key_len == ulNewLen) { - rv = pkcs11_util_convert_rv(atcab_read_serial_number(buf)); - (void)pkcs11_unlock_context(pLibCtx); + rv = pkcs11_token_convert_pin_to_key(pNewPin, ulNewLen, NULL, 0, buf, key_len); + } + else +#endif + { + if (CKR_OK == (rv = pkcs11_util_convert_rv(atcab_read_serial_number(buf)))) + { + rv = pkcs11_token_convert_pin_to_key(pNewPin, ulNewLen, buf, ATCA_SERIAL_NUM_SIZE, + buf, key_len); + } } - if (CKR_OK == rv) + if (is_ca_device) { - rv = pkcs11_token_convert_pin_to_key(pNewPin, ulNewLen, buf, ATCA_SERIAL_NUM_SIZE, - buf, (CK_LONG)sizeof(buf)); +#if ATCA_CA_SUPPORT + pin_slot = (ATCA_CHIP_OPT_IO_PROT_KEY_MASK & pSession->slot->cfg_zone.ChipOptions) >> ATCA_CHIP_OPT_IO_PROT_KEY_SHIFT; +#else + rv = CKR_GENERAL_ERROR; +#endif + } + else + { + pin_slot = pSession->slot->user_pin_handle; } - } - else - { - rv = pkcs11_token_convert_pin_to_key(pNewPin, ulNewLen, NULL, 0, buf, (CK_LONG)sizeof(buf)); - } - pin_slot = (ATCA_CHIP_OPT_IO_PROT_KEY_MASK & pSession->slot->cfg_zone.ChipOptions) >> ATCA_CHIP_OPT_IO_PROT_KEY_SHIFT; + if (CKR_OK == rv) + { + rv = atcab_write_zone(ATCA_ZONE_DATA, pin_slot, 0, 0, buf, sizeof(buf)); + } - if (CKR_OK == rv) - { - rv = atcab_write_zone(ATCA_ZONE_DATA, pin_slot, 0, 0, buf, sizeof(buf)); + (void)pkcs11_unlock_context(pLibCtx); } /* Lock the pin once it has been written */ diff --git a/module.xml b/module.xml index a4a287f8c..7c2183cdb 100644 --- a/module.xml +++ b/module.xml @@ -1,4 +1,4 @@ - + diff --git a/package.xml b/package.xml index 493d68c2f..3a9b4067f 100644 --- a/package.xml +++ b/package.xml @@ -1,6 +1,6 @@ - + diff --git a/python/cryptoauthlib/iface.py b/python/cryptoauthlib/iface.py index 76950e258..4caec8e22 100644 --- a/python/cryptoauthlib/iface.py +++ b/python/cryptoauthlib/iface.py @@ -89,6 +89,13 @@ class _ATCASWI(Structure): ('bus', c_uint8)] +class _ATCASPI(Structure): + """SPI HAL configuration""" + _fields_ = [('bus', c_uint8), + ('select_pin', c_uint8), + ('baud', c_uint32)] + + class _ATCAUART(Structure): """Generic UART HAL configuration""" _fields_ = [('port', c_int), @@ -124,6 +131,7 @@ class _ATCAIfaceParams(Union): """HAL Configurations supported by the library (this is a union)""" _fields_ = [('atcai2c', _ATCAI2C), ('atcaswi', _ATCASWI), + ('atcaspi', _ATCASPI), ('atcauart', _ATCAUART), ('atcahid', _ATCAHID), ('atcacustom', _ATCACUSTOM)] diff --git a/python/cryptoauthlib/library.py b/python/cryptoauthlib/library.py index 8465d2740..514a0f617 100644 --- a/python/cryptoauthlib/library.py +++ b/python/cryptoauthlib/library.py @@ -24,6 +24,7 @@ import os.path import json from ctypes import * +from ctypes.util import find_library from .exceptions import LibraryLoadError from .atcaenum import AtcaEnum @@ -77,20 +78,11 @@ def load_cryptoauthlib(lib=None): if lib is not None: _CRYPTO_LIB = lib else: - curr_path = os.path.abspath(os.path.dirname(__file__)) - os.environ['PATH'] = os.path.dirname(__file__) + ';' + os.environ['PATH'] - if os.path.exists(os.path.join(curr_path, "cryptoauth.dll")): - _CRYPTO_LIB = cdll.LoadLibrary(os.path.join(curr_path, "cryptoauth.dll")) - elif os.path.exists(os.path.join(curr_path, "libcryptoauth.so")): - _CRYPTO_LIB = cdll.LoadLibrary(os.path.join(curr_path, "libcryptoauth.so")) - elif os.path.exists(os.path.join(curr_path, "libcryptoauth.dylib")): - _CRYPTO_LIB = cdll.LoadLibrary(os.path.join(curr_path, "libcryptoauth.dylib")) - else: - # Try to find a system installed version - try: - _CRYPTO_LIB = cdll.LoadLibrary('libcryptoauth.so') - except: - raise LibraryLoadError('Unable to find cryptoauthlib. You may need to reinstall') + try: + os.environ['PATH'] = os.path.dirname(__file__) + os.pathsep + os.environ['PATH'] + _CRYPTO_LIB = cdll.LoadLibrary(find_library('cryptoauth')) + except: + raise LibraryLoadError('Unable to find cryptoauthlib. You may need to reinstall') def get_cryptoauthlib(): diff --git a/release_notes.md b/release_notes.md index ae0231d28..44a44f6ca 100644 --- a/release_notes.md +++ b/release_notes.md @@ -1,6 +1,29 @@ # Microchip Cryptoauthlib Release Notes +## Release v3.3.1 (04/23/2021) + +### New features + - Core support for kit protocol over serial ports (i.e. tty/COM ports) + - PKCS11 support for TA100 auth sessions + +### Fixes + - Fix mbedtls integration combinations that would produce unexpected + behavior. All variations of sign/verify _ALT now work as expected + given a configured key (for example if a key is configured as a stored public + and VERIFY_ALT is enabled then library will perform a stored key verify rather + than an external public key load and verify) + - Added mbedtls integration tests to confirm that integrations are working + on a target platform as expected. These generally bootstrap using NIST example + vectors before using the validated functions/algorithms to test the remaining + integration. + - Clean up warnings when run with very strict settings (-Wall -Wextra -pedantic -Werror) + - Fix false wake errors when baud rate switching for I2C + - Fix for I2C errors that could be created on the bus when there are devices + on the bus that support general calls - this fix should also correct + linux zero length kernel messages when enabled. + - Fix ESP32 HAL to work with the updated HAL structure. + ## Release v3.3.0 (01/22/2021) ### API Updates diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 0ba1bd3ab..efaade1d4 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -8,8 +8,10 @@ file(GLOB TEST_JWT_SRC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "jwt/*.c") file(GLOB TEST_TNG_SRC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "tng/*.c") file(GLOB TEST_API_ATCAB RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "api_atcab/*.c") file(GLOB TEST_API_CALIB RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "api_calib/*.c") +file(GLOB TEST_API_CRYPTO RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "api_crypto/*.c") file(GLOB TEST_API_TALIB RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "api_talib/*.c") file(GLOB TEST_VECTORS_SRC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "vectors/*.c") +file(GLOB TEST_MBEDTLDS_SRC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "mbedtls/*.c") file(GLOB TEST_SRC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.c") file(GLOB UNITY_SRC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "../third_party/unity/*.c") @@ -19,6 +21,7 @@ set(CRYPTOAUTH_TEST_SRC ${TEST_SRC} ${TEST_ATCACERT_SRC} ${TEST_API_ATCAB} ${TEST_API_CALIB} + ${TEST_API_CRYPTO} ${TEST_VECTORS_SRC}) if(ATCA_TA100_SUPPORT) @@ -34,14 +37,20 @@ set(CRYPTOAUTH_TEST_SRC ${CRYPTOAUTH_TEST_SRC} ${TEST_CUSTOM_CMD_SRC}) source_group("External Files" FILES ${TEST_CUSTOM_CMD_SRC}) endif() +if(ATCA_MBEDTLS) +set(CRYPTOAUTH_TEST_SRC ${CRYPTOAUTH_TEST_SRC} ${TEST_MBEDTLDS_SRC}) +endif() + add_executable(cryptoauth_test ${CRYPTOAUTH_TEST_SRC} ${UNITY_SRC}) include_directories(cryptoauth_test ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../ ${CMAKE_CURRENT_SOURCE_DIR}/api_atcab ${CMAKE_CURRENT_SOURCE_DIR}/api_calib + ${CMAKE_CURRENT_SOURCE_DIR}/api_crypto ${CMAKE_CURRENT_SOURCE_DIR}/api_talib ${CMAKE_CURRENT_SOURCE_DIR}/../lib + ${CMAKE_CURRENT_SOURCE_DIR}/../third_party ${CMAKE_CURRENT_SOURCE_DIR}/../third_party/mbedtls/include ${CMAKE_CURRENT_SOURCE_DIR}/../third_party/wolfssl ${CMAKE_CURRENT_BINARY_DIR}/../lib) diff --git a/test/api_atcab/atca_tests_aes_ccm.c b/test/api_atcab/atca_tests_aes_ccm.c index 4debd6273..38e50fa52 100644 --- a/test/api_atcab/atca_tests_aes_ccm.c +++ b/test/api_atcab/atca_tests_aes_ccm.c @@ -99,8 +99,9 @@ TEST(atca_cmd_basic_test, aes_ccm_auth_encrypt) uint8_t ciphertext[48]; uint8_t tag[AES_DATA_SIZE]; uint8_t tag_size; + size_t i; - for (int i = 0; i < (sizeof(ccm_test_array) / sizeof(aes_ccm_test_vectors)); i++) + for (i = 0; i < (sizeof(ccm_test_array) / sizeof(aes_ccm_test_vectors)); i++) { test_data = (aes_ccm_test_vectors*)&ccm_test_array[i]; @@ -133,8 +134,9 @@ TEST(atca_cmd_basic_test, aes_ccm_auth_decrypt) atca_aes_ccm_ctx_t ctx; uint8_t plaintext[48]; bool is_verified; + size_t i; - for (int i = 0; i < (sizeof(ccm_test_array) / sizeof(aes_ccm_test_vectors)); i++) + for (i = 0; i < (sizeof(ccm_test_array) / sizeof(aes_ccm_test_vectors)); i++) { test_data = (aes_ccm_test_vectors*)&ccm_test_array[i]; diff --git a/test/api_atcab/atca_tests_secureboot.c b/test/api_atcab/atca_tests_secureboot.c index 9203d923c..eb1ba5375 100644 --- a/test/api_atcab/atca_tests_secureboot.c +++ b/test/api_atcab/atca_tests_secureboot.c @@ -74,7 +74,7 @@ TEST(atca_cmd_basic_test, sboot_digest) TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); //Calculate the digest for the sboot_dummy_image using software SHA256 - status = atcac_sw_sha2_256(sboot_dummy_image, sizeof(sboot_dummy_image), digest); + status = (ATCA_STATUS)atcac_sw_sha2_256(sboot_dummy_image, sizeof(sboot_dummy_image), digest); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); // Sign the digest @@ -111,7 +111,7 @@ TEST(atca_cmd_basic_test, sboot_digest_full_encrypted) // Calculate the digest for the message using software SHA256 - status = atcac_sw_sha2_256(sboot_dummy_image, sizeof(sboot_dummy_image), digest); + status = (ATCA_STATUS)atcac_sw_sha2_256(sboot_dummy_image, sizeof(sboot_dummy_image), digest); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); // Sign the message @@ -144,7 +144,7 @@ TEST(atca_cmd_basic_test, sboot_digest_fullstore_encrypted) test_assert_data_is_locked(); //Calculate the digest for the message using software SHA256 - status = atcac_sw_sha2_256(sboot_dummy_image, sizeof(sboot_dummy_image), digest); + status = (ATCA_STATUS)atcac_sw_sha2_256(sboot_dummy_image, sizeof(sboot_dummy_image), digest); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); // Sign the message diff --git a/test/api_atcab/atca_tests_sha.c b/test/api_atcab/atca_tests_sha.c index 09e6aff24..f4fb49436 100644 --- a/test/api_atcab/atca_tests_sha.c +++ b/test/api_atcab/atca_tests_sha.c @@ -261,9 +261,10 @@ static int read_rsp_int_value(FILE* file, const char* name, int* value) #endif static void test_basic_hw_sha2_256_nist_simple(const char* filename) { - #ifndef _WIN32 +#ifndef _WIN32 + ((void)filename); TEST_IGNORE_MESSAGE("Test only available under windows."); - #else +#else FILE* rsp_file = NULL; uint8_t md_ref[ATCA_SHA2_256_DIGEST_SIZE]; uint8_t md[sizeof(md_ref)]; diff --git a/test/api_crypto/test_crypto_pbkdf2.c b/test/api_crypto/test_crypto_pbkdf2.c new file mode 100644 index 000000000..ca98a48ce --- /dev/null +++ b/test/api_crypto/test_crypto_pbkdf2.c @@ -0,0 +1,84 @@ +/** + * \file + * \brief Tests for the CryptoAuthLib software crypto API. + * + * \copyright (c) 2015-2020 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include "atca_test.h" +#include "vectors/pbkdf2_sha256_vectors.h" + +TEST_GROUP(atca_crypto_pbkdf2_sw); + +TEST_SETUP(atca_crypto_pbkdf2_sw) +{ +} + +TEST_TEAR_DOWN(atca_crypto_pbkdf2_sw) +{ +} + +TEST(atca_crypto_pbkdf2_sw, vectors) +{ + ATCA_STATUS status; + const pbkdf2_sha256_test_vector * pVector = pbkdf2_sha256_test_vectors; + size_t i; + uint8_t result[128]; + + for (i = 0; i < pbkdf2_sha256_test_vectors_count; i++, pVector++) + { + status = atcac_pbkdf2_sha256(pVector->c, (uint8_t*)pVector->p, pVector->plen, (uint8_t*)pVector->s, + pVector->slen, result, pVector->dklen); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + TEST_ASSERT_EQUAL_MEMORY(pVector->dk, result, pVector->dklen); + } +} + +TEST(atca_cmd_basic_test, pdkdf2_hw_vectors) +{ + ATCA_STATUS status; + const pbkdf2_sha256_fixed_size_test_vector* pVector = pbkdf2_sha256_fixed_size_test_vectors; + size_t i; + uint8_t result[ATCA_SHA256_DIGEST_SIZE]; + uint16_t key_id = 6; + + status = atca_test_config_get_id(TEST_TYPE_HMAC, &key_id); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + for (i = 0; i < pbkdf2_sha256_fixed_size_test_vectors_count; i++, pVector++) + { + status = atcab_pbkdf2_sha256(pVector->c, key_id, (uint8_t*)pVector->s, pVector->slen, result, ATCA_SHA256_DIGEST_SIZE); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + TEST_ASSERT_EQUAL_MEMORY(pVector->dk, result, ATCA_SHA256_DIGEST_SIZE); + } +} + +t_test_case_info test_crypto_pbkdf2_info[] = +{ + { REGISTER_TEST_CASE(atca_crypto_pbkdf2_sw, vectors), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ECC | DEVICE_MASK(TA100) }, + { REGISTER_TEST_CASE(atca_cmd_basic_test, pdkdf2_hw_vectors), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ECC | DEVICE_MASK(TA100) }, + /* Array Termination element*/ + { (fp_test_case)NULL, (uint8_t)0 }, +}; + + diff --git a/test/api_crypto/test_crypto_pbkdf2.h b/test/api_crypto/test_crypto_pbkdf2.h new file mode 100644 index 000000000..f544257b7 --- /dev/null +++ b/test/api_crypto/test_crypto_pbkdf2.h @@ -0,0 +1,59 @@ +/** + * \file + * \brief Unity tests for the CryptoAuthLib software crypto API. + * + * \copyright (c) 2015-2020 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#ifndef ATCA_CRYPTO_TESTS_H_ +#define ATCA_CRYPTO_TESTS_H_ + +#include "third_party/unity/unity.h" + +int atca_crypto_sw_tests(int argc, char* argv[]); + +void test_atcac_sw_sha1_nist1(void); +void test_atcac_sw_sha1_nist2(void); +void test_atcac_sw_sha1_nist3(void); +void test_atcac_sw_sha1_nist_short(void); +void test_atcac_sw_sha1_nist_long(void); +void test_atcac_sw_sha1_nist_monte(void); +void test_atcac_sw_sha2_256_nist1(void); +void test_atcac_sw_sha2_256_nist2(void); +void test_atcac_sw_sha2_256_nist3(void); +void test_atcac_sw_sha2_256_nist_short(void); +void test_atcac_sw_sha2_256_nist_long(void); +void test_atcac_sw_sha2_256_nist_monte(void); + +void test_atcac_aes128_gcm(void); +void test_atcac_aes128_cmac(void); +void test_atcac_sha256_hmac(void); +void test_atcac_sha256_hmac_nist(void); + +void test_atcac_verify_nist(void); +void test_atcac_public(void); +void test_atcac_sign(void); +void test_atcac_derive_nist(void); + + +#endif diff --git a/test/atca_crypto_sw_tests.c b/test/atca_crypto_sw_tests.c index d6e4de2cc..8bbc4154d 100644 --- a/test/atca_crypto_sw_tests.c +++ b/test/atca_crypto_sw_tests.c @@ -25,11 +25,7 @@ * THIS SOFTWARE. */ -#ifdef _WIN32 -#include -#include -#include -#endif +#include "cryptoauthlib.h" #include "atca_crypto_sw_tests.h" #include "crypto/atca_crypto_sw.h" @@ -48,6 +44,9 @@ static const uint8_t nist_hash_msg3[] = "a"; int atca_crypto_sw_tests(int argc, char * argv[]) { + ((void)argc); + ((void)argv); + UnityBegin("atca_crypto_sw_tests.c"); RUN_TEST(test_atcac_sw_sha1_nist1); @@ -141,7 +140,7 @@ void test_atcac_sw_sha1_nist3(void) TEST_ASSERT_EQUAL_MEMORY(digest_ref, digest, sizeof(digest_ref)); } -#ifdef _WIN32 +#if defined(_WIN32) || defined(__linux__) static void hex_to_uint8(const char hex_str[2], uint8_t* num) { *num = 0; @@ -206,6 +205,14 @@ static int read_rsp_hex_value(FILE* file, const char* name, uint8_t* data, size_ { continue; } + else + { + size_t ln = strlen(line); + if (ln > 0 && line[ln-2] == '\r') + { + line[ln-1] = 0; + } + } if (memcmp(line, name, name_size) == 0) { @@ -239,6 +246,14 @@ static int read_rsp_int_value(FILE* file, const char* name, int* value) { continue; } + else + { + size_t ln = strlen(line); + if (ln > 0 && line[ln-2] == '\r') + { + line[ln-1] = 0; + } + } if (memcmp(line, name, name_size) == 0) { @@ -263,8 +278,9 @@ static int read_rsp_int_value(FILE* file, const char* name, int* value) static void test_atcac_sw_sha1_nist_simple(const char* filename) { -#ifndef _WIN32 - TEST_IGNORE_MESSAGE("Test only available under windows."); +#if !defined(_WIN32) && !defined(__linux__) + ((void)filename); + TEST_IGNORE_MESSAGE("Test is not available for this platform."); #else FILE* rsp_file = NULL; int ret = ATCA_SUCCESS; @@ -319,8 +335,8 @@ void test_atcac_sw_sha1_nist_long(void) void test_atcac_sw_sha1_nist_monte(void) { -#ifndef _WIN32 - TEST_IGNORE_MESSAGE("Test only available under windows."); +#if !defined(_WIN32) && !defined(__linux__) + TEST_IGNORE_MESSAGE("Test is not available for this platform."); #else FILE* rsp_file = NULL; int ret = ATCA_SUCCESS; @@ -418,8 +434,9 @@ void test_atcac_sw_sha2_256_nist3(void) static void test_atcac_sw_sha2_256_nist_simple(const char* filename) { -#ifndef _WIN32 - TEST_IGNORE_MESSAGE("Test only available under windows."); +#if !defined(_WIN32) && !defined(__linux__) + ((void)filename); + TEST_IGNORE_MESSAGE("Test is not available for this platform."); #else FILE* rsp_file = NULL; int ret = ATCA_SUCCESS; @@ -474,8 +491,8 @@ void test_atcac_sw_sha2_256_nist_long(void) void test_atcac_sw_sha2_256_nist_monte(void) { -#ifndef _WIN32 - TEST_IGNORE_MESSAGE("Test only available under windows."); +#if !defined(_WIN32) && !defined(__linux__) + TEST_IGNORE_MESSAGE("Test is not available for this platform."); #else FILE* rsp_file = NULL; int ret = ATCA_SUCCESS; @@ -518,7 +535,6 @@ void test_atcac_aes128_gcm(void) { ATCA_STATUS status; uint8_t test_index; - uint8_t aes_key_block = 0; uint8_t ciphertext[GCM_TEST_VECTORS_DATA_SIZE_MAX]; size_t ct_size; uint8_t plaintext[GCM_TEST_VECTORS_DATA_SIZE_MAX]; @@ -685,8 +701,6 @@ void test_atcac_aes128_cmac(void) } #endif -#define ATCA_SHA_DIGEST_SIZE 32 - void test_atcac_sha256_hmac(void) { ATCA_STATUS status = ATCA_GEN_FAIL; @@ -733,8 +747,8 @@ void test_atcac_sha256_hmac(void) void test_atcac_sha256_hmac_nist(void) { -#ifndef _WIN32 - TEST_IGNORE_MESSAGE("Test only available under windows."); +#if !defined(_WIN32) && !defined(__linux__) + TEST_IGNORE_MESSAGE("Test is not available for this platform."); #else FILE* rsp_file = NULL; int ret = ATCA_SUCCESS; @@ -799,7 +813,7 @@ void test_atcac_verify_nist(void) uint8_t digest[32]; atcac_pk_ctx pkey_ctx; ATCA_STATUS status; - int i; + size_t i; /* Test verification using [P-256,SHA-256] vectors */ for (i = 0; i < ecdsa_p256_test_vectors_count; i++) @@ -813,7 +827,7 @@ void test_atcac_verify_nist(void) memcpy(&signature[32], ecdsa_p256_test_vectors[i].S, 32); /* Hash the message */ - status = atcac_sw_sha2_256(&ecdsa_p256_test_vectors[i].Msg, sizeof(ecdsa_p256_test_vectors[i].Msg), digest); + status = atcac_sw_sha2_256(ecdsa_p256_test_vectors[i].Msg, sizeof(ecdsa_p256_test_vectors[i].Msg), digest); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); /* Initialize the key using the provided X,Y cordinantes */ @@ -922,7 +936,7 @@ void test_atcac_derive_nist(void) atcac_pk_ctx pub_ctx; uint8_t result[32]; size_t result_size; - int i; + size_t i; /* Test verification using [P-256] vectors */ for (i = 0; i < ecdh_p256_test_vectors_count; i++) @@ -933,7 +947,7 @@ void test_atcac_derive_nist(void) memcpy(&pubkey[32], ecdh_p256_test_vectors[i].QCAVSy, 32); (void)atcac_pk_init(&pub_ctx, pubkey, sizeof(pubkey), 0, true); - (void)atcac_pk_init(&pri_ctx, ecdh_p256_test_vectors[i].dIUT, 32, 0, false); + (void)atcac_pk_init(&pri_ctx, (uint8_t*)ecdh_p256_test_vectors[i].dIUT, 32, 0, false); result_size = sizeof(result); status = atcac_pk_derive(&pri_ctx, &pub_ctx, result, &result_size); @@ -947,5 +961,4 @@ void test_atcac_derive_nist(void) } } - #endif diff --git a/test/atca_test.c b/test/atca_test.c index d506ff3fa..83b070c5e 100644 --- a/test/atca_test.c +++ b/test/atca_test.c @@ -163,6 +163,18 @@ t_test_case_info* tng_tests[] = }; +#ifdef ATCA_MBEDTLS + +extern t_test_case_info test_mbedtls_ecdsa_info[]; + +t_test_case_info* crypto_integration_tests[] = +{ + test_mbedtls_ecdsa_info, + (t_test_case_info*)NULL, /* Array Termination element*/ +}; +#endif + + void RunAllTests(t_test_case_info** tests_list) { t_test_case_info* sp_current_test; @@ -216,6 +228,25 @@ void RunTNGTests(void) RunAllTests(tng_tests); } +#if defined(ATCA_MBEDTLS) || defined(ATCA_WOLFSSL) || defined(ATCA_OPENSSL) +void RunCryptoIntegrationTests(void) +{ + RunAllTests(crypto_integration_tests); +} +#endif + +extern t_test_case_info test_crypto_pbkdf2_info[]; + +t_test_case_info* pbkdf2_tests[] = +{ + test_crypto_pbkdf2_info, + (t_test_case_info*)NULL, /* Array Termination element*/ +}; + +void RunPbkdf2Tests(void) +{ + RunAllTests(pbkdf2_tests); +} #ifdef ATCA_NO_HEAP ATCA_DLL ATCADevice _gDevice; @@ -230,7 +261,7 @@ void atca_test_assert_config_is_unlocked(UNITY_LINE_TYPE from_line) bool is_locked = false; ATCA_STATUS status = atcab_is_config_locked(&is_locked); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + UNITY_TEST_ASSERT_EQUAL_INT(ATCA_SUCCESS, status, from_line, NULL); if (is_locked) { @@ -243,7 +274,7 @@ void atca_test_assert_config_is_locked(UNITY_LINE_TYPE from_line) bool is_locked = false; ATCA_STATUS status = atcab_is_config_locked(&is_locked); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + UNITY_TEST_ASSERT_EQUAL_INT(ATCA_SUCCESS, status, from_line, NULL); if (!is_locked) { @@ -256,7 +287,7 @@ void atca_test_assert_data_is_unlocked(UNITY_LINE_TYPE from_line) bool is_locked = false; ATCA_STATUS status = atcab_is_data_locked(&is_locked); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + UNITY_TEST_ASSERT_EQUAL_INT(ATCA_SUCCESS, status, from_line, NULL); if (is_locked) { diff --git a/test/atca_test.h b/test/atca_test.h index a015db657..fbf9be02c 100644 --- a/test/atca_test.h +++ b/test/atca_test.h @@ -79,7 +79,7 @@ typedef struct extern bool g_atca_test_quiet_mode; void RunAllTests(t_test_case_info** tests_list); -int run_test(int argc, char* argv[], void* fptest); +int run_test(int argc, char* argv[], void (*fptest)(void)); void run_all_talib_tests(void); extern const char* TEST_GROUP_atca_cmd_basic_test; @@ -129,6 +129,8 @@ extern t_test_case_info jwt_unit_test_info[]; extern t_test_case_info tng_atca_unit_test_info[]; extern t_test_case_info tng_atcacert_client_unit_test_info[]; +extern t_test_case_info test_crypto_pbkdf2_info[]; + void test_assert_interface_init(void); void test_assert_interface_deinit(void); @@ -196,6 +198,8 @@ void RunBasicOtpZero(void); void RunAllBasicTests(void); void RunAllFeatureTests(void); void RunTNGTests(void); +void RunCryptoIntegrationTests(void); +void RunPbkdf2Tests(void); /* Setup & Configuration */ void atca_test_config_set_ifacecfg(ATCAIfaceCfg * ifacecfg); @@ -233,12 +237,16 @@ int run_unit_tests(int argc, char* argv[]); int run_otpzero_tests(int argc, char* argv[]); int run_helper_tests(int argc, char* argv[]); int run_all_tests(int argc, char* argv[]); + ATCA_STATUS set_chip_mode(uint8_t i2c_user_extra_add, uint8_t ttl_enable, uint8_t watchdog, uint8_t clock_divider); void update_chip_mode(uint8_t* chip_mode, uint8_t i2c_user_extra_add, uint8_t ttl_enable, uint8_t watchdog, uint8_t clock_divider); int set_clock_divider_m0(int argc, char* argv[]); int set_clock_divider_m1(int argc, char* argv[]); int set_clock_divider_m2(int argc, char* argv[]); int run_tng_tests(int argc, char* argv[]); +int run_crypto_integration_tests(int argc, char* argv[]); +int run_pbkdf2_tests(int argc, char* argv[]); + ATCA_STATUS check_clock_divider(int argc, char* argv[]); #ifdef _WIN32 diff --git a/test/atca_test_config.c b/test/atca_test_config.c index 2566de7aa..0b0f10293 100644 --- a/test/atca_test_config.c +++ b/test/atca_test_config.c @@ -97,6 +97,7 @@ int select_204(int argc, char* argv[]) #if defined(ATCA_HAL_CUSTOM) && defined(ATCA_ATSHA204A_SUPPORT) return select_204_custom(argc, argv); #else + ((void)argc); return select_device(ATSHA204A, NULL != argv); #endif } @@ -106,6 +107,7 @@ int select_206(int argc, char* argv[]) #if defined(ATCA_HAL_CUSTOM) && defined(ATCA_ATSHA206A_SUPPORT) return select_206_custom(argc, argv); #else + ((void)argc); return select_device(ATSHA206A, NULL != argv); #endif } @@ -115,6 +117,7 @@ int select_108(int argc, char* argv[]) #if defined(ATCA_HAL_CUSTOM) && defined(ATCA_ATECC108A_SUPPORT) return select_108_custom(argc, argv); #else + ((void)argc); return select_device(ATECC108A, NULL != argv); #endif } @@ -124,6 +127,7 @@ int select_508(int argc, char* argv[]) #if defined(ATCA_HAL_CUSTOM) && defined(ATCA_ATECC508A_SUPPORT) return select_508_custom(argc, argv); #else + ((void)argc); return select_device(ATECC508A, NULL != argv); #endif } @@ -133,6 +137,7 @@ int select_608(int argc, char* argv[]) #if defined(ATCA_HAL_CUSTOM) && defined(ATCA_ATECC608_SUPPORT) return select_608_custom(argc, argv); #else + ((void)argc); return select_device(ATECC608, NULL != argv); #endif } @@ -142,6 +147,7 @@ int select_ta100(int argc, char* argv[]) #if defined(ATCA_HAL_CUSTOM) && defined(ATCA_TA100_SUPPORT) return select_ta100_custom(argc, argv); #else + ((void)argc); return select_device(TA100, NULL != argv); #endif } @@ -151,6 +157,7 @@ int select_ecc204(int argc, char* argv[]) #if defined(ATCA_HAL_CUSTOM) && defined(ATCA_ECC204_SUPPORT) return select_ecc204_custom(argc, argv); #else + ((void)argc); return select_device(ECC204, NULL != argv); #endif } @@ -342,6 +349,8 @@ static int opt_address(int argc, char* argv[]) static int opt_quiet(int argc, char* argv[]) { + ((void)argc); + ((void)argv); g_atca_test_quiet_mode = true; return 1; } diff --git a/test/atca_test_console.c b/test/atca_test_console.c index 4c5d75194..15004f7c7 100644 --- a/test/atca_test_console.c +++ b/test/atca_test_console.c @@ -65,6 +65,9 @@ int read_config(int argc, char* argv[]) size_t config_size = 0; size_t i = 0; + ((void)argc); + ((void)argv); + status = atcab_init(gCfg); if (status != ATCA_SUCCESS) { @@ -118,6 +121,9 @@ int lock_status(int argc, char* argv[]) ATCA_STATUS status; bool is_locked = false; + ((void)argc); + ((void)argv); + if ((status = is_config_locked(&is_locked)) != ATCA_SUCCESS) { printf("is_device_locked() failed with ret=0x%08X\r\n", status); @@ -159,6 +165,9 @@ int do_randoms(int argc, char* argv[]) size_t displen = sizeof(displayStr); int i; + ((void)argc); + ((void)argv); + if ((gCfg->devtype == ATSHA206A) || (ECC204 == gCfg->devtype)) { printf("Selected Device doesn't support random command\r\n"); @@ -202,6 +211,9 @@ int info(int argc, char* argv[]) char displaystr[15]; size_t displaylen = sizeof(displaystr); + ((void)argc); + ((void)argv); + status = get_info(revision); if (status == ATCA_SUCCESS) { @@ -219,6 +231,9 @@ int read_sernum(int argc, char* argv[]) char displaystr[30]; size_t displaylen = sizeof(displaystr); + ((void)argc); + ((void)argv); + status = get_serial_no(serialnum); if (status == ATCA_SUCCESS) { @@ -282,6 +297,9 @@ int lock_config_zone(int argc, char* argv[]) ATCA_STATUS status; uint8_t ch = 0; + ((void)argc); + ((void)argv); + if (gCfg->devtype == ATSHA206A) { printf("ATSHA206A doesn't support lock command\r\n"); @@ -327,6 +345,9 @@ int lock_data_zone(int argc, char* argv[]) ATCA_STATUS status; uint8_t ch = 0; + ((void)argc); + ((void)argv); + if (!g_atca_test_quiet_mode) { int ret; @@ -409,7 +430,7 @@ ATCA_STATUS get_serial_no(uint8_t* sernum) return status; } -int run_test(int argc, char* argv[], void* fptest) +int run_test(int argc, char* argv[], void (*fptest)(void)) { if (CMD_PROCESSOR_MAX_ARGS > argc) { @@ -458,7 +479,7 @@ int run_all_tests(int argc, char* argv[]) return status; } - status = lock_status(argc, argv); + status = (ATCA_STATUS)lock_status(argc, argv); if (status != ATCA_SUCCESS) { printf("lock_status() failed with ret=0x%08X\r\n", status); @@ -482,13 +503,13 @@ int run_all_tests(int argc, char* argv[]) return status; } - status = lock_config_zone(argc, argv); + status = (ATCA_STATUS)lock_config_zone(argc, argv); if (status != ATCA_SUCCESS) { printf("lock_config_zone() failed with ret=0x%08X\r\n", status); return status; } - status = lock_status(argc, argv); + status = (ATCA_STATUS)lock_status(argc, argv); if (status != ATCA_SUCCESS) { printf("lock_status() failed with ret=0x%08X\r\n", status); @@ -505,13 +526,13 @@ int run_all_tests(int argc, char* argv[]) return status; } - status = lock_data_zone(argc, argv); + status = (ATCA_STATUS)lock_data_zone(argc, argv); if (status != ATCA_SUCCESS) { printf("lock_data_zone() failed with ret=0x%08X\r\n", status); return status; } - status = lock_status(argc, argv); + status = (ATCA_STATUS)lock_status(argc, argv); if (status != ATCA_SUCCESS) { printf("lock_status() failed with ret=0x%08X\r\n", status); @@ -589,3 +610,15 @@ int run_tng_tests(int argc, char* argv[]) atcab_release(); return 0; } + +#if defined(ATCA_MBEDTLS) || defined(ATCA_WOLFSSL) || defined(ATCA_OPENSSL) +int run_crypto_integration_tests(int argc, char* argv[]) +{ + return run_test(argc, argv, RunCryptoIntegrationTests); +} +#endif + +int run_pbkdf2_tests(int argc, char* argv[]) +{ + return run_test(argc, argv, RunPbkdf2Tests); +} diff --git a/test/atca_utils_atecc608.c b/test/atca_utils_atecc608.c index a7d20b096..d2663d138 100644 --- a/test/atca_utils_atecc608.c +++ b/test/atca_utils_atecc608.c @@ -58,6 +58,9 @@ ATCA_STATUS check_clock_divider(int argc, char* argv[]) ATCA_STATUS status; uint8_t chip_mode = 0; + ((void)argc); + ((void)argv); + if (!(ATECC608 == gCfg->devtype)) { printf("Current device doesn't support clock divider settings (only ATECC608)\r\n"); @@ -179,6 +182,9 @@ ATCA_STATUS set_chip_mode(uint8_t i2c_user_extra_add, uint8_t ttl_enable, uint8_ int set_clock_divider_m0(int argc, char* argv[]) { + ((void)argc); + ((void)argv); + ATCA_STATUS status = set_chip_mode(0xFF, 0xFF, ATCA_CHIPMODE_WATCHDOG_SHORT, ATCA_CHIPMODE_CLOCK_DIV_M0); if (status == ATCA_SUCCESS) @@ -190,6 +196,9 @@ int set_clock_divider_m0(int argc, char* argv[]) int set_clock_divider_m1(int argc, char* argv[]) { + ((void)argc); + ((void)argv); + ATCA_STATUS status = set_chip_mode(0xFF, 0xFF, ATCA_CHIPMODE_WATCHDOG_SHORT, ATCA_CHIPMODE_CLOCK_DIV_M1); if (status == ATCA_SUCCESS) @@ -201,6 +210,9 @@ int set_clock_divider_m1(int argc, char* argv[]) int set_clock_divider_m2(int argc, char* argv[]) { + ((void)argc); + ((void)argv); + // Additionally set watchdog to long settings (~13s) as some commands // can't complete in time on the faster watchdog setting. ATCA_STATUS status = set_chip_mode(0xFF, 0xFF, ATCA_CHIPMODE_WATCHDOG_LONG, ATCA_CHIPMODE_CLOCK_DIV_M2); diff --git a/test/atcacert/test_atcacert_date.c b/test/atcacert/test_atcacert_date.c index c35129142..0ef277777 100644 --- a/test/atcacert/test_atcacert_date.c +++ b/test/atcacert/test_atcacert_date.c @@ -1087,7 +1087,7 @@ TEST(atcacert_date_enc, bad_format) set_tm(&ts, 2013, 11, 10, 9, 8, 7); - ret = atcacert_date_enc(-1, &ts, ts_str, &ts_str_size); + ret = atcacert_date_enc((atcacert_date_format_t)-1, &ts, ts_str, &ts_str_size); TEST_ASSERT_EQUAL(ATCACERT_E_BAD_PARAMS, ret); ret = atcacert_date_enc(DATEFMT_RFC5280_GEN + 1, &ts, ts_str, &ts_str_size); @@ -1760,13 +1760,13 @@ TEST(atcacert_date_get_max_date, bad_params) int ret = ATCACERT_E_SUCCESS; atcacert_tm_utc_t ts; - ret = atcacert_date_get_max_date(-1, &ts); + ret = atcacert_date_get_max_date((atcacert_date_format_t)-1, &ts); TEST_ASSERT_EQUAL(ATCACERT_E_BAD_PARAMS, ret); ret = atcacert_date_get_max_date(DATEFMT_ISO8601_SEP, NULL); TEST_ASSERT_EQUAL(ATCACERT_E_BAD_PARAMS, ret); - ret = atcacert_date_get_max_date(-1, NULL); + ret = atcacert_date_get_max_date((atcacert_date_format_t)-1, NULL); TEST_ASSERT_EQUAL(ATCACERT_E_BAD_PARAMS, ret); } @@ -1856,10 +1856,10 @@ TEST(atcacert_date_dec_compcert, bad_params) ret = atcacert_date_dec_compcert(NULL, DATEFMT_RFC5280_GEN, &issue_date, &expire_date); TEST_ASSERT_EQUAL(ATCACERT_E_BAD_PARAMS, ret); - ret = atcacert_date_dec_compcert(enc_dates, -1, &issue_date, &expire_date); + ret = atcacert_date_dec_compcert(enc_dates, (atcacert_date_format_t)-1, &issue_date, &expire_date); TEST_ASSERT_EQUAL(ATCACERT_E_BAD_PARAMS, ret); - ret = atcacert_date_dec_compcert(NULL, -1, &issue_date, &expire_date); + ret = atcacert_date_dec_compcert(NULL, (atcacert_date_format_t)-1, &issue_date, &expire_date); TEST_ASSERT_EQUAL(ATCACERT_E_BAD_PARAMS, ret); ret = atcacert_date_dec_compcert(enc_dates, DATEFMT_RFC5280_GEN, NULL, &expire_date); @@ -1868,10 +1868,10 @@ TEST(atcacert_date_dec_compcert, bad_params) ret = atcacert_date_dec_compcert(NULL, DATEFMT_RFC5280_GEN, NULL, &expire_date); TEST_ASSERT_EQUAL(ATCACERT_E_BAD_PARAMS, ret); - ret = atcacert_date_dec_compcert(enc_dates, -1, NULL, &expire_date); + ret = atcacert_date_dec_compcert(enc_dates, (atcacert_date_format_t)-1, NULL, &expire_date); TEST_ASSERT_EQUAL(ATCACERT_E_BAD_PARAMS, ret); - ret = atcacert_date_dec_compcert(NULL, -1, NULL, &expire_date); + ret = atcacert_date_dec_compcert(NULL, (atcacert_date_format_t)-1, NULL, &expire_date); TEST_ASSERT_EQUAL(ATCACERT_E_BAD_PARAMS, ret); ret = atcacert_date_dec_compcert(enc_dates, DATEFMT_RFC5280_GEN, &issue_date, NULL); @@ -1880,10 +1880,10 @@ TEST(atcacert_date_dec_compcert, bad_params) ret = atcacert_date_dec_compcert(NULL, DATEFMT_RFC5280_GEN, &issue_date, NULL); TEST_ASSERT_EQUAL(ATCACERT_E_BAD_PARAMS, ret); - ret = atcacert_date_dec_compcert(enc_dates, -1, &issue_date, NULL); + ret = atcacert_date_dec_compcert(enc_dates, (atcacert_date_format_t)-1, &issue_date, NULL); TEST_ASSERT_EQUAL(ATCACERT_E_BAD_PARAMS, ret); - ret = atcacert_date_dec_compcert(NULL, -1, &issue_date, NULL); + ret = atcacert_date_dec_compcert(NULL, (atcacert_date_format_t)-1, &issue_date, NULL); TEST_ASSERT_EQUAL(ATCACERT_E_BAD_PARAMS, ret); ret = atcacert_date_dec_compcert(enc_dates, DATEFMT_RFC5280_GEN, NULL, NULL); @@ -1892,10 +1892,10 @@ TEST(atcacert_date_dec_compcert, bad_params) ret = atcacert_date_dec_compcert(NULL, DATEFMT_RFC5280_GEN, NULL, NULL); TEST_ASSERT_EQUAL(ATCACERT_E_BAD_PARAMS, ret); - ret = atcacert_date_dec_compcert(enc_dates, -1, NULL, NULL); + ret = atcacert_date_dec_compcert(enc_dates, (atcacert_date_format_t)-1, NULL, NULL); TEST_ASSERT_EQUAL(ATCACERT_E_BAD_PARAMS, ret); - ret = atcacert_date_dec_compcert(NULL, -1, NULL, NULL); + ret = atcacert_date_dec_compcert(NULL, (atcacert_date_format_t)-1, NULL, NULL); TEST_ASSERT_EQUAL(ATCACERT_E_BAD_PARAMS, ret); } @@ -2006,7 +2006,7 @@ TEST(atcacert_date_dec, bad_format) size_t ts_str_size = sizeof(ts_str); atcacert_tm_utc_t ts; - ret = atcacert_date_dec(-1, ts_str, ts_str_size, &ts); + ret = atcacert_date_dec((atcacert_date_format_t)-1, ts_str, ts_str_size, &ts); TEST_ASSERT_EQUAL(ATCACERT_E_BAD_PARAMS, ret); ret = atcacert_date_dec(DATEFMT_RFC5280_GEN + 1, ts_str, ts_str_size, &ts); diff --git a/test/atcacert/test_atcacert_def.c b/test/atcacert/test_atcacert_def.c index a0f5ccfd9..38aefee74 100644 --- a/test/atcacert/test_atcacert_def.c +++ b/test/atcacert/test_atcacert_def.c @@ -5667,6 +5667,10 @@ static atcacert_cert_element_t g_auth_key_cert_element = { .offset = 331, .count = 20 }, + { + TF_NONE, + TF_NONE + } }; TEST(atcacert_cert_build, start_signer_no_ca_key) diff --git a/test/cbuf.h b/test/cbuf.h index 715eebe03..d8e9ca703 100644 --- a/test/cbuf.h +++ b/test/cbuf.h @@ -103,7 +103,7 @@ * contained in the circular buffer. */ -#define CBUF_Len(cbuf) ((typeof( cbuf.m_putIdx ))(( cbuf.m_putIdx ) - ( cbuf.m_getIdx ))) +#define CBUF_Len(cbuf) ((__typeof__( cbuf.m_putIdx ))(( cbuf.m_putIdx ) - ( cbuf.m_getIdx ))) /** * Appends an element to the end of the circular buffer. The @@ -245,4 +245,4 @@ EntryType m_entry[ Size ]; /** @} */ -#endif // CBUF_H \ No newline at end of file +#endif // CBUF_H diff --git a/test/cmd-processor.c b/test/cmd-processor.c index a5f42685c..c782636ce 100644 --- a/test/cmd-processor.c +++ b/test/cmd-processor.c @@ -28,14 +28,6 @@ // Undefine the Unity FAIL macro so it doesn't conflict with the ASF definition #undef FAIL -#if !defined(_WIN32) && !defined(__linux__) && !defined(__XC32__) && !defined(__APPLE__) && !defined(ESP32) -#ifdef ATMEL_START -#include "atmel_start.h" -#else -#include -#endif -#endif - #include #ifndef _WIN32 #include "cbuf.h" @@ -50,17 +42,17 @@ #include "api_talib/test_talib.h" #endif -static void help(int argc, char* argv[]); +static int help(int argc, char* argv[]); #if defined(_WIN32) || defined(__linux__) || defined(__APPLE__) -static void call_exit(int argc, char* argv[]); +static int call_exit(int argc, char* argv[]); #endif // *INDENT-OFF* - Preserve formatting static t_menu_info mas_menu_info[] = { - { "help", "Display Menu", (fp_menu_handler)help }, + { "help", "Display Menu", help }, #ifdef ATCA_ATSHA204A_SUPPORT { "sha204", "Set Target Device to ATSHA204A", select_204 }, #endif @@ -82,27 +74,27 @@ static t_menu_info mas_menu_info[] = #ifdef ATCA_TA100_SUPPORT { "ta100", "Set Target Device to TA100", select_ta100 }, #endif - { "info", "Get the Chip Revision", (fp_menu_handler)info }, + { "info", "Get the Chip Revision", info }, { "sernum", "Get the Chip Serial Number", read_sernum }, { "rand", "Generate Some Random Numbers", do_randoms }, - { "readcfg", "Read the Config Zone", (fp_menu_handler)read_config }, + { "readcfg", "Read the Config Zone", read_config }, { "lockstat", "Zone Lock Status", lock_status }, #ifdef ATCA_TEST_LOCK_ENABLE - { "lockcfg", "Lock the Config Zone", (fp_menu_handler)lock_config }, - { "lockdata", "Lock Data and OTP Zones", (fp_menu_handler)lock_data }, - { "all", "Run all unit tests, locking as needed.", (fp_menu_handler)run_all_tests }, + { "lockcfg", "Lock the Config Zone", lock_config }, + { "lockdata", "Lock Data and OTP Zones", lock_data }, + { "all", "Run all unit tests, locking as needed.", run_all_tests }, #endif - { "tng", "Run unit tests on TNG type part.", (fp_menu_handler)run_tng_tests }, + { "tng", "Run unit tests on TNG type part.", run_tng_tests }, #ifndef DO_NOT_TEST_BASIC_UNIT - { "basic", "Run Basic Test on Selected Device", (fp_menu_handler)run_basic_tests }, + { "basic", "Run Basic Test on Selected Device", run_basic_tests }, #ifdef ATCA_TEST_LOCK_ENABLE - { "otpzero", "Zero Out OTP Zone", (fp_menu_handler)run_otpzero_tests }, + { "otpzero", "Zero Out OTP Zone", run_otpzero_tests }, #endif - { "util", "Run Helper Function Tests", (fp_menu_handler)run_helper_tests }, + { "util", "Run Helper Function Tests", run_helper_tests }, #ifdef ATCA_ATECC608_SUPPORT - { "clkdivm0", "Set ATECC608 to ClockDivider M0(0x00)", (fp_menu_handler)set_clock_divider_m0}, - { "clkdivm1", "Set ATECC608 to ClockDivider M1(0x05)", (fp_menu_handler)set_clock_divider_m1}, - { "clkdivm2", "Set ATECC608 to ClockDivider M2(0x0D)", (fp_menu_handler)set_clock_divider_m2}, + { "clkdivm0", "Set ATECC608 to ClockDivider M0(0x00)", set_clock_divider_m0 }, + { "clkdivm1", "Set ATECC608 to ClockDivider M1(0x05)", set_clock_divider_m1 }, + { "clkdivm2", "Set ATECC608 to ClockDivider M2(0x0D)", set_clock_divider_m2 }, #endif #endif /* DO_NOT_TEST_BASIC_UNIT */ #ifndef DO_NOT_TEST_CERT @@ -110,7 +102,11 @@ static t_menu_info mas_menu_info[] = { "cio", "Run Unit Test on Cert I/O", certio_unit_tests }, #endif #ifndef DO_NOT_TEST_SW_CRYPTO - { "crypto", "Run Unit Tests for Software Crypto Functions", (fp_menu_handler)atca_crypto_sw_tests}, + { "crypto", "Run Unit Tests for Software Crypto Functions", atca_crypto_sw_tests }, +#endif + { "pbkdf2", "Run pbkdf2 tests", run_pbkdf2_tests }, +#if defined(ATCA_MBEDTLS) + { "crypto_int", "Run crypto library integration tests", run_crypto_integration_tests }, #endif #if ATCA_TA_SUPPORT { "config", "Create testing handles in TA100 device", talib_configure_device }, @@ -119,7 +115,7 @@ static t_menu_info mas_menu_info[] = { "talib", "Run talib tests", run_talib_tests }, #endif #if defined(_WIN32) || defined(__linux__) || defined(__APPLE__) - { "exit", "Exit the test application", (fp_menu_handler)call_exit }, + { "exit", "Exit the test application", call_exit }, #endif { NULL, NULL, NULL }, }; @@ -238,9 +234,13 @@ static int parse_cmd(char *command, size_t max_len) static int exit_code; -void call_exit(int argc, char* argv[]) +int call_exit(int argc, char* argv[]) { + ((void)argc); + ((void)argv); + exit_code = 1; + return 0; } int main(int argc, char* argv[]) @@ -309,8 +309,11 @@ void atca_test_task(void) #endif -static void help(int argc, char* argv[]) +static int help(int argc, char* argv[]) { + ((void)argc); + ((void)argv); + uint8_t index = 0; printf("Usage:\r\n"); @@ -319,4 +322,6 @@ static void help(int argc, char* argv[]) printf("%s - %s\r\n", mas_menu_info[index].menu_cmd, mas_menu_info[index].menu_cmd_description); index++; } + + return 0; } diff --git a/test/mbedtls/test_mbedtls_ecdsa.c b/test/mbedtls/test_mbedtls_ecdsa.c new file mode 100644 index 000000000..d2c4f17d9 --- /dev/null +++ b/test/mbedtls/test_mbedtls_ecdsa.c @@ -0,0 +1,202 @@ +/** + * \file + * \brief Validation test of the mbedtls integration of hardware accelerated + * ECDSA operations + * + * \copyright (c) 2015-2020 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include "atca_test.h" + +#if defined(ATCA_MBEDTLS) && defined(MBEDTLS_ECDSA_C) +#include "third_party/atca_mbedtls_patch.h" + +#include "mbedtls/atca_mbedtls_wrap.h" +#include "vectors/ecdsa_nist_vectors.h" + +/** \brief This test uses NIST provided vectors for testing verify integration - It may be hardware accelerated . + */ +TEST(atca_cmd_basic_test, mbedtls_ecdsa_verify_nist) +{ + uint8_t pubkey[64]; + uint8_t signature[74]; + uint8_t digest[32]; + atcac_pk_ctx pkey_ctx; + int status; + size_t i; + mbedtls_mpi r; + mbedtls_mpi s; + + /* Test verification using [P-256,SHA-256] vectors */ + for (i = 0; i < ecdsa_p256_test_vectors_count; i++) + { + size_t sig_len = sizeof(signature); + + /* Copy pubkey */ + memcpy(pubkey, ecdsa_p256_test_vectors[i].Qx, 32); + memcpy(&pubkey[32], ecdsa_p256_test_vectors[i].Qy, 32); + + mbedtls_mpi_init(&r); + mbedtls_mpi_init(&s); + + /* Copy the signature */ + mbedtls_mpi_read_binary(&r, ecdsa_p256_test_vectors[i].R, 32); + mbedtls_mpi_read_binary(&s, ecdsa_p256_test_vectors[i].S, 32); + + /* Create the asn.1 signature */ + status = mbedtls_ecdsa_signature_to_asn1(&r, &s, signature, &sig_len); + + /* Clean up before checking the result */ + mbedtls_mpi_free(&r); + mbedtls_mpi_free(&s); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + /* Hash the message */ + status = atcac_sw_sha2_256(ecdsa_p256_test_vectors[i].Msg, sizeof(ecdsa_p256_test_vectors[i].Msg), digest); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + /* Initialize the key using the provided X,Y cordinantes */ + status = atcac_pk_init(&pkey_ctx, pubkey, sizeof(pubkey), 0, true); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + /* Perform the verification */ + status = mbedtls_pk_verify(&pkey_ctx, MBEDTLS_MD_SHA256, digest, sizeof(digest), signature, sig_len); + + /* Make sure to free the key before testing the result of the verify */ + atcac_pk_free(&pkey_ctx); + + /* Check verification result against the expected success/failure */ + if (ecdsa_p256_test_vectors[i].Result) + { + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + } + else + { + TEST_ASSERT_NOT_EQUAL(ATCA_SUCCESS, status); + } + } +} + +/** \brief Check verify with a stored key in a device + */ +TEST(atca_cmd_basic_test, mbedtls_ecdsa_verify_nist_stored_key) +{ + uint8_t pubkey[64]; + uint8_t signature[74]; + uint8_t digest[32]; + atcac_pk_ctx pkey_ctx; + ATCA_STATUS status; + mbedtls_mpi r; + mbedtls_mpi s; + size_t i; + + /* Test verification using [P-256,SHA-256] vectors */ + for (i = 0; i < ecdsa_p256_test_vectors_count; i++) + { + size_t sig_len = sizeof(signature); + + /* Copy pubkey */ + memcpy(pubkey, ecdsa_p256_test_vectors[i].Qx, 32); + memcpy(&pubkey[32], ecdsa_p256_test_vectors[i].Qy, 32); + + mbedtls_mpi_init(&r); + mbedtls_mpi_init(&s); + + /* Copy the signature */ + mbedtls_mpi_read_binary(&r, ecdsa_p256_test_vectors[i].R, 32); + mbedtls_mpi_read_binary(&s, ecdsa_p256_test_vectors[i].S, 32); + + /* Create the asn.1 signature */ + status = mbedtls_ecdsa_signature_to_asn1(&r, &s, signature, &sig_len); + + /* Clean up before checking the result */ + mbedtls_mpi_free(&r); + mbedtls_mpi_free(&s); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + /* Hash the message */ + status = atcac_sw_sha2_256(ecdsa_p256_test_vectors[i].Msg, sizeof(ecdsa_p256_test_vectors[i].Msg), digest); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + /* Initialize the key using the provided X,Y cordinantes */ + status = atcab_write_pubkey(15, pubkey); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + status = atca_mbedtls_pk_init(&pkey_ctx, 15); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + /* Perform the verification */ + status = mbedtls_pk_verify(&pkey_ctx, MBEDTLS_MD_SHA256, digest, sizeof(digest), signature, sig_len); + + /* Make sure to free the key before testing the result of the verify */ + atcac_pk_free(&pkey_ctx); + + /* Check verification result against the expected success/failure */ + if (ecdsa_p256_test_vectors[i].Result) + { + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + } + else + { + TEST_ASSERT_NOT_EQUAL(ATCA_SUCCESS, status); + } + } +} + + +/** \brief Having confirmed the verify passes the NIST vectors the sign operation can be tested + */ +TEST(atca_cmd_basic_test, mbedtls_ecdsa_sign) +{ + int status; + atcac_pk_ctx pkey_ctx; + uint8_t digest[32]; + uint8_t signature[74] = { 0 }; + size_t sig_len = sizeof(signature); + + status = atca_mbedtls_pk_init(&pkey_ctx, 0); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + status = mbedtls_pk_sign(&pkey_ctx, MBEDTLS_MD_SHA256, digest, sizeof(digest), signature, &sig_len, NULL, NULL); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + /* Perform the verification */ + status = mbedtls_pk_verify(&pkey_ctx, MBEDTLS_MD_SHA256, digest, sizeof(digest), signature, sig_len); + + /* Make sure to free the key before testing the result of the verify */ + atcac_pk_free(&pkey_ctx); + + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + +} + +t_test_case_info test_mbedtls_ecdsa_info[] = +{ + { REGISTER_TEST_CASE(atca_cmd_basic_test, mbedtls_ecdsa_verify_nist), DEVICE_MASK_ECC | DEVICE_MASK(TA100) }, + { REGISTER_TEST_CASE(atca_cmd_basic_test, mbedtls_ecdsa_verify_nist_stored_key), DEVICE_MASK_ECC | DEVICE_MASK(TA100) }, + { REGISTER_TEST_CASE(atca_cmd_basic_test, mbedtls_ecdsa_sign), DEVICE_MASK_ECC | DEVICE_MASK(TA100) }, + /* Array Termination element*/ + { (fp_test_case)NULL, (uint8_t)0 }, +}; + +#endif diff --git a/test/vectors/pbkdf2_sha256_vectors.c b/test/vectors/pbkdf2_sha256_vectors.c new file mode 100644 index 000000000..3f67d1cbb --- /dev/null +++ b/test/vectors/pbkdf2_sha256_vectors.c @@ -0,0 +1,123 @@ +/** + * \file + * \brief Embedded vectors for the PBKDF2 algorithm + */ + +#include "cryptoauthlib.h" +#include "pbkdf2_sha256_vectors.h" + +const uint8_t pbkdf2_sha256_test_vector_dk1[] = { + 0x12, 0x0f, 0xb6, 0xcf, 0xfc, 0xf8, 0xb3, 0x2c, 0x43, 0xe7, 0x22, 0x52, 0x56, 0xc4, 0xf8, 0x37, + 0xa8, 0x65, 0x48, 0xc9 +}; + +const uint8_t pbkdf2_sha256_test_vector_dk2[] = { + 0xae, 0x4d, 0x0c, 0x95, 0xaf, 0x6b, 0x46, 0xd3, 0x2d, 0x0a, 0xdf, 0xf9, 0x28, 0xf0, 0x6d, 0xd0, + 0x2a, 0x30, 0x3f, 0x8e +}; + +const uint8_t pbkdf2_sha256_test_vector_dk3[] = { + 0xc5, 0xe4, 0x78, 0xd5, 0x92, 0x88, 0xc8, 0x41, 0xaa, 0x53, 0x0d, 0xb6, 0x84, 0x5c, 0x4c, 0x8d, + 0x96, 0x28, 0x93, 0xa0 +}; + +const uint8_t pbkdf2_sha256_test_vector_dk4[] = { + 0x34, 0x8c, 0x89, 0xdb, 0xcb, 0xd3, 0x2b, 0x2f, 0x32, 0xd8, 0x14, 0xb8, 0x11, 0x6e, 0x84, 0xcf, + 0x2b, 0x17, 0x34, 0x7e, 0xbc, 0x18, 0x00, 0x18, 0x1c +}; + +const uint8_t pbkdf2_sha256_test_vector_dk5[] = { + 0x55, 0xac, 0x04, 0x6e, 0x56, 0xe3, 0x08, 0x9f, 0xec, 0x16, 0x91, 0xc2, 0x25, 0x44, 0xb6, 0x05, + 0xf9, 0x41, 0x85, 0x21, 0x6d, 0xde, 0x04, 0x65, 0xe6, 0x8b, 0x9d, 0x57, 0xc2, 0x0d, 0xac, 0xbc, + 0x49, 0xca, 0x9c, 0xcc, 0xf1, 0x79, 0xb6, 0x45, 0x99, 0x16, 0x64, 0xb3, 0x9d, 0x77, 0xef, 0x31, + 0x7c, 0x71, 0xb8, 0x45, 0xb1, 0xe3, 0x0b, 0xd5, 0x09, 0x11, 0x20, 0x41, 0xd3, 0xa1, 0x97, 0x83, + 0xc2, 0x94, 0xe8, 0x50, 0x15, 0x03, 0x90, 0xe1, 0x16, 0x0c, 0x34, 0xd6, 0x2e, 0x96, 0x65, 0xd6, + 0x59, 0xae, 0x49, 0xd3, 0x14, 0x51, 0x0f, 0xc9, 0x82, 0x74, 0xcc, 0x79, 0x68, 0x19, 0x68, 0x10, + 0x4b, 0x8f, 0x89, 0x23, 0x7e, 0x69, 0xb2, 0xd5, 0x49, 0x11, 0x18, 0x68, 0x65, 0x8b, 0xe6, 0x2f, + 0x59, 0xbd, 0x71, 0x5c, 0xac, 0x44, 0xa1, 0x14, 0x7e, 0xd5, 0x31, 0x7c, 0x9b, 0xae, 0x6b, 0x2a +}; + + +const pbkdf2_sha256_test_vector pbkdf2_sha256_test_vectors[] = { + { + 1, + "password", + 8, + "salt", + 4, + pbkdf2_sha256_test_vector_dk1, + sizeof(pbkdf2_sha256_test_vector_dk1) + }, + { + 2, + "password", + 8, + "salt", + 4, + pbkdf2_sha256_test_vector_dk2, + sizeof(pbkdf2_sha256_test_vector_dk2) + }, + { + 4096, + "password", + 8, + "salt", + 4, + pbkdf2_sha256_test_vector_dk3, + sizeof(pbkdf2_sha256_test_vector_dk3) + }, + { + 4096, + "passwordPASSWORDpassword", + 24, + "saltSALTsaltSALTsaltSALTsaltSALTsalt", + 36, + pbkdf2_sha256_test_vector_dk4, + sizeof(pbkdf2_sha256_test_vector_dk4) + }, + { + 1, + "passwd", + 6, + "salt", + 4, + pbkdf2_sha256_test_vector_dk5, + sizeof(pbkdf2_sha256_test_vector_dk5) + } +}; + +const size_t pbkdf2_sha256_test_vectors_count = sizeof(pbkdf2_sha256_test_vectors) / sizeof(pbkdf2_sha256_test_vector); + +const pbkdf2_sha256_fixed_size_test_vector pbkdf2_sha256_fixed_size_test_vectors[] = +{ + { + 1, + "salt", + 4, + { + 0xa5, 0xd9, 0x32, 0x53, 0x59, 0x53, 0x19, 0xec, 0x5a, 0x91, 0x8e, 0x22, 0xc7, 0xdd, 0x5f, 0x1b, + 0x7e, 0x3e, 0x9a, 0x9a, 0x15, 0x0f, 0xe1, 0x46, 0x2a, 0x35, 0xba, 0x48, 0x01, 0xc1, 0xdf, 0x8a + } + }, + { + 2, + "salt", + 4, + { + 0xe8, 0xfb, 0x33, 0x1d, 0x4b, 0x8e, 0x86, 0xae, 0x54, 0x6d, 0x5a, 0xbe, 0x75, 0x18, 0x11, 0x7c, + 0xa3, 0x07, 0x65, 0x11, 0x46, 0xd3, 0x52, 0xcc, 0xa3, 0x8c, 0x3d, 0xc2, 0x0f, 0x90, 0x80, 0xa6 + } + }, + { + 100, + "salt", + 4, + { + 0xc7, 0x29, 0x5e, 0x39, 0x8a, 0x39, 0x98, 0x93, 0xc8, 0xdd, 0x61, 0x4d, 0x24, 0x41, 0x38, 0x18, + 0x5d, 0xf1, 0xbe, 0x93, 0xaf, 0xb9, 0x84, 0x3f, 0x3a, 0x3f, 0x06, 0xe3, 0x10, 0x0b, 0x85, 0x73 + } + }, +}; + +const size_t pbkdf2_sha256_fixed_size_test_vectors_count = sizeof(pbkdf2_sha256_fixed_size_test_vectors) / sizeof(pbkdf2_sha256_fixed_size_test_vector); + diff --git a/test/vectors/pbkdf2_sha256_vectors.h b/test/vectors/pbkdf2_sha256_vectors.h new file mode 100644 index 000000000..2ff63dc8b --- /dev/null +++ b/test/vectors/pbkdf2_sha256_vectors.h @@ -0,0 +1,36 @@ +/** + * \file + * \brief Embedded vectors for the PBKDF2 algorithm + */ + +#ifndef PBKDF2_VECTORS_H +#define PBKDF2_VECTORS_H + + +typedef struct +{ + uint32_t c; + const char * p; + size_t plen; + const char * s; + size_t slen; + const uint8_t * dk; + size_t dklen; +} pbkdf2_sha256_test_vector; + +typedef struct +{ + uint32_t c; + const char* s; + size_t slen; + uint8_t dk[32]; +} pbkdf2_sha256_fixed_size_test_vector; + +extern const pbkdf2_sha256_test_vector pbkdf2_sha256_test_vectors[]; +extern const size_t pbkdf2_sha256_test_vectors_count; + +extern const pbkdf2_sha256_fixed_size_test_vector pbkdf2_sha256_fixed_size_test_vectors[]; +extern const size_t pbkdf2_sha256_fixed_size_test_vectors_count; + + +#endif /* PBKDF2_VECTORS_H */ diff --git a/third_party/hal/esp32/hal_esp32_i2c.c b/third_party/hal/esp32/hal_esp32_i2c.c index f9168e16b..cd8cb7887 100644 --- a/third_party/hal/esp32/hal_esp32_i2c.c +++ b/third_party/hal/esp32/hal_esp32_i2c.c @@ -20,8 +20,10 @@ #include "esp_log.h" #include "cryptoauthlib.h" -#define SDA_PIN 16 -#define SCL_PIN 17 +#define I2C0_SDA_PIN 16 +#define I2C0_SCL_PIN 17 +#define I2C1_SDA_PIN 21 +#define I2C1_SCL_PIN 22 #define ACK_CHECK_EN 0x1 /*!< I2C master will check ack from slave*/ #define ACK_CHECK_DIS 0x0 /*!< I2C master will not check ack from slave */ #define ACK_VAL 0x0 /*!< I2C ack value */ @@ -36,35 +38,38 @@ typedef struct atcaI2Cmaster { int id; + i2c_config_t conf; int ref_ct; - int bus_index; } ATCAI2CMaster_t; -ATCAI2CMaster_t *i2c_hal_data[MAX_I2C_BUSES]; -int i2c_bus_ref_ct = 0; -i2c_config_t conf; +ATCAI2CMaster_t i2c_hal_data[MAX_I2C_BUSES]; const char* TAG = "HAL_I2C"; +ATCA_STATUS status; + /** \brief method to change the bus speec of I2C * \param[in] iface interface on which to change bus speed * \param[in] speed baud rate (typically 100000 or 400000) */ -void hal_i2c_change_baud(ATCAIface iface, uint32_t speed) +ATCA_STATUS hal_i2c_change_baud(ATCAIface iface, uint32_t speed) { esp_err_t rc; ATCAIfaceCfg *cfg = atgetifacecfg(iface); int bus = cfg->atcai2c.bus; - conf.master.clk_speed = speed; - rc = i2c_param_config(i2c_hal_data[bus]->id, &conf); + i2c_hal_data[bus].conf.master.clk_speed = speed; + + rc = i2c_param_config(i2c_hal_data[bus].id, &i2c_hal_data[bus].conf); if (rc == ESP_OK) { -// ESP_LOGD(TAG, "Baudrate Changed"); + //ESP_LOGD(TAG, "Baudrate Changed"); + return ATCA_SUCCESS; } else { -// ESP_LOGW(TAG, "Baudrate Change Failed"); + //ESP_LOGW(TAG, "Baudrate Change Failed"); + return ATCA_COMM_FAIL; } } @@ -84,63 +89,60 @@ void hal_i2c_change_baud(ATCAIface iface, uint32_t speed) * \param[in] cfg - interface configuration * \return ATCA_SUCCESS on success, otherwise an error code. */ -ATCA_STATUS hal_i2c_init(void *hal, ATCAIfaceCfg *cfg) +ATCA_STATUS hal_i2c_init(ATCAIface iface, ATCAIfaceCfg *cfg) { - esp_err_t rc; + esp_err_t rc = ESP_FAIL; int bus = cfg->atcai2c.bus; - ATCAHAL_t *phal = (ATCAHAL_t*)hal; - - if (i2c_bus_ref_ct == 0) - { - for (int i = 0; i < MAX_I2C_BUSES; i++) - { - i2c_hal_data[i] = NULL; - } - } - - i2c_bus_ref_ct++; if (bus >= 0 && bus < MAX_I2C_BUSES) { - if (i2c_hal_data[bus] == NULL) + if (0 == i2c_hal_data[bus].ref_ct) { - i2c_hal_data[bus] = malloc(sizeof(ATCAI2CMaster_t)); - i2c_hal_data[bus]->ref_ct = 1; + i2c_hal_data[bus].ref_ct = 1; + i2c_hal_data[bus].conf.mode = I2C_MODE_MASTER; + i2c_hal_data[bus].conf.sda_pullup_en = GPIO_PULLUP_DISABLE; + i2c_hal_data[bus].conf.scl_pullup_en = GPIO_PULLUP_DISABLE; + i2c_hal_data[bus].conf.master.clk_speed = 100000; //cfg->atcai2c.baud; switch (bus) { case 0: - i2c_hal_data[bus]->id = I2C_NUM_0; + i2c_hal_data[bus].id = I2C_NUM_0; + i2c_hal_data[bus].conf.sda_io_num = I2C0_SDA_PIN; + i2c_hal_data[bus].conf.scl_io_num = I2C0_SCL_PIN; break; case 1: - i2c_hal_data[bus]->id = I2C_NUM_1; + i2c_hal_data[bus].id = I2C_NUM_1; + i2c_hal_data[bus].conf.sda_io_num = I2C1_SDA_PIN; + i2c_hal_data[bus].conf.scl_io_num = I2C1_SCL_PIN; + break; + default: break; } - conf.mode = I2C_MODE_MASTER; - conf.sda_io_num = SDA_PIN; - conf.scl_io_num = SCL_PIN; - conf.sda_pullup_en = GPIO_PULLUP_DISABLE; - conf.scl_pullup_en = GPIO_PULLUP_DISABLE; - conf.master.clk_speed = 100000; //cfg->atcai2c.baud; // ESP_LOGI(TAG, "Configuring I2C"); - rc = i2c_param_config(i2c_hal_data[bus]->id, &conf); + rc = i2c_param_config(i2c_hal_data[bus].id, &i2c_hal_data[bus].conf); // ESP_LOGD(TAG, "I2C Param Config: %s", esp_err_to_name(rc)); - rc = i2c_driver_install(i2c_hal_data[bus]->id, I2C_MODE_MASTER, 0, 0, 0); + rc = i2c_driver_install(i2c_hal_data[bus].id, I2C_MODE_MASTER, 0, 0, 0); // ESP_LOGD(TAG, "I2C Driver Install; %s", esp_err_to_name(rc)); - i2c_hal_data[bus]->bus_index = bus; } else { - i2c_hal_data[bus]->ref_ct++; + i2c_hal_data[bus].ref_ct++; } - phal->hal_data = i2c_hal_data[bus]; + iface->hal_data = &i2c_hal_data[bus]; + } + if (ESP_OK == rc) + { return ATCA_SUCCESS; } -// ESP_LOGE(TAG, "I2C init failed"); - return ATCA_COMM_FAIL; + else + { + //ESP_LOGE(TAG, "I2C init failed"); + return ATCA_COMM_FAIL; + } } /** \brief HAL implementation of I2C post init @@ -159,7 +161,7 @@ ATCA_STATUS hal_i2c_post_init(ATCAIface iface) * \param[in] txlength number of bytes to send * \return ATCA_SUCCESS on success, otherwise an error code. */ -ATCA_STATUS hal_i2c_send(ATCAIface iface, uint8_t word_address, uint8_t *txdata, int txlength) +ATCA_STATUS hal_i2c_send(ATCAIface iface, uint8_t address, uint8_t *txdata, int txlength) { ATCAIfaceCfg *cfg = iface->mIfaceCFG; esp_err_t rc; @@ -169,18 +171,12 @@ ATCA_STATUS hal_i2c_send(ATCAIface iface, uint8_t word_address, uint8_t *txdata, return ATCA_BAD_PARAM; } - if (0xFF != word_address) - { - txdata[0] = word_address; // insert the Word Address Value, Command token - txlength++; // account for word address value byte. - } - -// ESP_LOGD(TAG, "txdata: %p , txlength: %d", txdata, txlength); -// ESP_LOG_BUFFER_HEXDUMP(TAG, txdata, txlength, 3); + //ESP_LOGD(TAG, "txdata: %p , txlength: %d", txdata, txlength); + //ESP_LOG_BUFFER_HEXDUMP(TAG, txdata, txlength, 3); i2c_cmd_handle_t cmd = i2c_cmd_link_create(); (void)i2c_master_start(cmd); - (void)i2c_master_write_byte(cmd, cfg->atcai2c.slave_address | I2C_MASTER_WRITE, ACK_CHECK_EN); + (void)i2c_master_write_byte(cmd, address | I2C_MASTER_WRITE, ACK_CHECK_EN); (void)i2c_master_write(cmd, txdata, txlength, ACK_CHECK_EN); (void)i2c_master_stop(cmd); rc = i2c_master_cmd_begin(cfg->atcai2c.bus, cmd, 10); @@ -197,149 +193,46 @@ ATCA_STATUS hal_i2c_send(ATCAIface iface, uint8_t word_address, uint8_t *txdata, } /** \brief HAL implementation of I2C receive function - * \param[in] iface Device to interact with. - * \param[in] word_address device transaction type - * \param[out] rxdata Data received will be returned here. - * \param[in,out] rxlength As input, the size of the rxdata buffer. - * As output, the number of bytes received. + * \param[in] iface Device to interact with. + * \param[in] address Device address + * \param[out] rxdata Data received will be returned here. + * \param[in,out] rxlength As input, the size of the rxdata buffer. + * As output, the number of bytes received. * \return ATCA_SUCCESS on success, otherwise an error code. */ -ATCA_STATUS hal_i2c_receive(ATCAIface iface, uint8_t word_address, uint8_t *rxdata, uint16_t *rxlength) +ATCA_STATUS hal_i2c_receive(ATCAIface iface, uint8_t address, uint8_t *rxdata, uint16_t *rxlength) { ATCAIfaceCfg *cfg = iface->mIfaceCFG; esp_err_t rc; i2c_cmd_handle_t cmd; - int high = 0; - int low = 0; - uint8_t min_response_size = 4; - uint16_t read_length = 2; - + ATCA_STATUS status = ATCA_COMM_FAIL; + if ((NULL == cfg) || (NULL == rxlength) || (NULL == rxdata)) { return ATCA_TRACE(ATCA_INVALID_POINTER, "NULL pointer encountered"); } - *rxlength = 0; - //Read Length byte i.e. first byte from device - - do + cmd = i2c_cmd_link_create(); + (void)i2c_master_start(cmd); + (void)i2c_master_write_byte(cmd, address | I2C_MASTER_READ, ACK_CHECK_EN); + if (*rxlength > 1) { - /*Send Word address to device...*/ - retries = cfg->rx_retries; - while (retries-- > 0 && status != ATCA_SUCCESS) - { - status = hal_i2c_send(iface, word_address, &word_address, 0); - - } - if (ATCA_SUCCESS != status) - { - ATCA_TRACE(status, "hal_i2c_send - failed"); - break; - } - -#if ATCA_TA_SUPPORT - /*Set read length.. Check for register reads or 1 byte reads*/ - if ((word_address == ATCA_MAIN_PROCESSOR_RD_CSR) || (word_address == ATCA_FAST_CRYPTO_RD_FSR) - || (rxdata_max_size == 1)) - { - read_length = 1; - } -#endif - - status = ATCA_COMM_FAIL; - cmd = i2c_cmd_link_create(); - (void)i2c_master_start(cmd); - (void)i2c_master_write_byte(cmd, cfg->atcai2c.slave_address | I2C_MASTER_READ, ACK_CHECK_EN); - if (read_length == 1) - { - (void)i2c_master_read_byte(cmd, rxdata, NACK_VAL); - } - else - { - (void)i2c_master_read(cmd, rxdata, read_length, ACK_VAL); - } - - rc = i2c_master_cmd_begin(cfg->atcai2c.bus, cmd, 10); - (void)i2c_cmd_link_delete(cmd); - - if (ESP_OK == rc) - { - status = ATCA_SUCCESS; - } - - if (ATCA_SUCCESS != status) - { - ATCA_TRACE(status, "hal read - failed"); - break; - } - - if (1 == read_length) - { - ATCA_TRACE(status, "1 byte read completed"); - break; - } - - /*Calculate bytes to read based on device response*/ - if (cfg->devtype == TA100) - { - read_length = ((uint16_t)rxdata[0] * 256) + rxdata[1]; - min_response_size += 1; - } - else - { - read_length = rxdata[0]; - } - - if (read_length > rxdata_max_size) - { - status = ATCA_TRACE(ATCA_SMALL_BUFFER, "rxdata is small buffer"); - break; - - } - - if (read_length < min_response_size) - { - status = ATCA_TRACE(ATCA_RX_FAIL, "packet size is invalid"); - break; - } - - status = ATCA_COMM_FAIL; - if (read_length > 1) - { - cmd = i2c_cmd_link_create(); - if (read_length > 2) - { - (void)i2c_master_read(cmd, &rxdata[2], read_length - 3, ACK_VAL); - } - (void)i2c_master_read_byte(cmd, rxdata + read_length - 1, NACK_VAL); - (void)i2c_master_stop(cmd); - rc = i2c_master_cmd_begin(cfg->atcai2c.bus, cmd, 10); - (void)i2c_cmd_link_delete(cmd); - } - else - { - cmd = i2c_cmd_link_create(); - (void)i2c_master_stop(cmd); - rc = i2c_master_cmd_begin(cfg->atcai2c.bus, cmd, 10); - (void)i2c_cmd_link_delete(cmd); - } + (void)i2c_master_read(cmd, rxdata, *rxlength - 1, ACK_VAL); + } + (void)i2c_master_read_byte(cmd, rxdata + (size_t)*rxlength - 1, NACK_VAL); + (void)i2c_master_stop(cmd); + rc = i2c_master_cmd_begin(cfg->atcai2c.bus, cmd, 10); + (void)i2c_cmd_link_delete(cmd); - if (ESP_OK == rc) - { - status = ATCA_SUCCESS; - } + //ESP_LOG_BUFFER_HEXDUMP(TAG, rxdata, *rxlength, 3); - if (status != ATCA_SUCCESS) - { - ATCA_TRACE(status, "hal read - failed"); - break; - } -// ESP_LOG_BUFFER_HEX(TAG, rxdata, *rxlength); + if (ESP_OK == rc) + { + status = ATCA_SUCCESS; } - while (0); - *rxlength = read_length; return status; + } /** \brief manages reference count on given bus and releases resource if no more refences exist @@ -350,123 +243,35 @@ ATCA_STATUS hal_i2c_release(void *hal_data) { ATCAI2CMaster_t *hal = (ATCAI2CMaster_t*)hal_data; - i2c_bus_ref_ct--; - if (hal && --(hal->ref_ct) <= 0 && i2c_hal_data[hal->bus_index] != NULL) + if (hal && --(hal->ref_ct) <= 0) { - i2c_driver_delete(hal->bus_index); - free(i2c_hal_data[hal->bus_index]); - i2c_hal_data[hal->bus_index] = NULL; + i2c_driver_delete(hal->id); } return ATCA_SUCCESS; } -/** \brief wake up CryptoAuth device using I2C bus - * \param[in] iface interface to logical device to wakeup +/** \brief Perform control operations for the kit protocol + * \param[in] iface Interface to interact with. + * \param[in] option Control parameter identifier + * \param[in] param Optional pointer to parameter value + * \param[in] paramlen Length of the parameter * \return ATCA_SUCCESS on success, otherwise an error code. */ -ATCA_STATUS hal_i2c_wake(ATCAIface iface) +ATCA_STATUS hal_i2c_control(ATCAIface iface, uint8_t option, void* param, size_t paramlen) { - ATCAIfaceCfg *cfg = atgetifacecfg(iface); -// uint32_t bdrt = cfg->atcai2c.baud; - uint16_t rxlen; - uint8_t data[4] = { 0 }; - const uint8_t expected[4] = { 0x04, 0x11, 0x33, 0x43 }; - -// if (bdrt != 100000) { -// hal_i2c_change_baud(iface, 100000); -// } - - // 0x00 as wake up pulse - i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + (void)param; + (void)paramlen; - (void)i2c_master_start(cmd); - (void)i2c_master_write_byte(cmd, I2C_MASTER_WRITE, ACK_CHECK_DIS); - (void)i2c_master_stop(cmd); - (void)i2c_master_cmd_begin(cfg->atcai2c.bus, cmd, 10); - (void)i2c_cmd_link_delete(cmd); - - atca_delay_ms(10); // wait tWHI + tWLO which is configured based on device type and configuration structure - -// if (bdrt != 100000) -// { -// hal_i2c_change_baud(iface, cfg->atcai2c.baud); -// } - - rxlen = 4; - hal_i2c_receive(iface, data, &rxlen); - if (memcmp(data, expected, 4) == 0) + if (iface && iface->mIfaceCFG) { -// ESP_LOGI(TAG, "I2C wake successful"); - return ATCA_SUCCESS; + if (ATCA_HAL_CHANGE_BAUD == option) + { + return hal_i2c_change_baud(iface, *(uint32_t*)param); + } + else + { + return ATCA_UNIMPLEMENTED; + } } -// ESP_LOGW(TAG, "I2C wake failed"); - return ATCA_COMM_FAIL; -} - -/** \brief idle CryptoAuth device using I2C bus - * \param[in] iface interface to logical device to idle - * \return ATCA_SUCCESS on success, otherwise an error code. - */ -ATCA_STATUS hal_i2c_idle(ATCAIface iface) -{ - ATCAIfaceCfg *cfg = atgetifacecfg(iface); - uint8_t idle_data = 0x02; - i2c_cmd_handle_t cmd = i2c_cmd_link_create(); - - (void)i2c_master_start(cmd); - (void)i2c_master_write_byte(cmd, cfg->atcai2c.slave_address | I2C_MASTER_WRITE, ACK_CHECK_EN); - (void)i2c_master_write(cmd, &idle_data, 1, ACK_CHECK_DIS); - (void)i2c_master_stop(cmd); - (void)i2c_master_cmd_begin(cfg->atcai2c.bus, cmd, 10); - (void)i2c_cmd_link_delete(cmd); -// ESP_LOGI(TAG, "IDLE Command Sent"); - return ATCA_SUCCESS; + return ATCA_BAD_PARAM; } - -/** \brief sleep CryptoAuth device using I2C bus - * \param[in] iface interface to logical device to sleep - * \return ATCA_SUCCESS on success, otherwise an error code. - */ -ATCA_STATUS hal_i2c_sleep(ATCAIface iface) -{ - ATCAIfaceCfg *cfg = atgetifacecfg(iface); - uint8_t sleep_data = 0x01; - - i2c_cmd_handle_t cmd = i2c_cmd_link_create(); - - (void)i2c_master_start(cmd); - (void)i2c_master_write_byte(cmd, cfg->atcai2c.slave_address | I2C_MASTER_WRITE, ACK_CHECK_EN); - (void)i2c_master_write(cmd, &sleep_data, 1, ACK_CHECK_DIS); - (void)i2c_master_stop(cmd); - (void)i2c_master_cmd_begin(cfg->atcai2c.bus, cmd, 10); - (void)i2c_cmd_link_delete(cmd); -// ESP_LOGI(TAG, "hal_i2c_sleep"); - - return ATCA_SUCCESS; -} - -/** \brief discover i2c buses available for this hardware - * this maintains a list of logical to physical bus mappings freeing the application - * of the a-priori knowledge - * \param[in] i2c_buses - an array of logical bus numbers - * \param[in] max_buses - maximum number of buses the app wants to attempt to discover - * \return ATCA_SUCCESS - */ -ATCA_STATUS hal_i2c_discover_buses(int i2c_buses[], int max_buses) -{ -// ESP_LOGI(TAG, "hal_i2c_discover_buses"); - return ATCA_UNIMPLEMENTED; -} - -/** \brief discover any CryptoAuth devices on a given logical bus number - * \param[in] bus_num logical bus number on which to look for CryptoAuth devices - * \param[out] cfg pointer to head of an array of interface config structures which get filled in by this method - * \param[out] found number of devices found on this bus - * \return ATCA_SUCCESS - */ -ATCA_STATUS hal_i2c_discover_devices(int bus_num, ATCAIfaceCfg *cfg, int *found) -{ -// ESP_LOGI(TAG, "hal_i2c_discover_devices"); - return ATCA_UNIMPLEMENTED; -} - diff --git a/third_party/hal/esp32/hal_esp32_timer.c b/third_party/hal/esp32/hal_esp32_timer.c index bf935070f..0cf6f566d 100644 --- a/third_party/hal/esp32/hal_esp32_timer.c +++ b/third_party/hal/esp32/hal_esp32_timer.c @@ -19,6 +19,11 @@ extern void ets_delay_us(uint32_t); +void atca_delay_us(uint32_t delay) +{ + ets_delay_us(delay); +} + #ifdef ATCA_USE_RTOS_TIMER void atca_delay_ms_internal(uint32_t msec) #else