Usage of Oscore #63
Replies: 5 comments 4 replies
-
|
Hi Robert, did you check the oscore samples in the samples/linux_oscore? Here you can find the correct configuration for the
|
Beta Was this translation helpful? Give feedback.
-
|
Can you try to run the samples and tell me if you are getting the same error? Can you share with me a minimal example project that I can test locally? |
Beta Was this translation helpful? Give feedback.
-
|
Are you trying to implement a server or a client or both? Note that the normal flow of OSCORE looks like in the picture. The context of the client (and server) stays the same for calling both coap2oscore and oscore2coap. Note that in test 1 we are testing a client sending request and receiving a response. We use the same context (c_client) for coap2oscore and oscore2coap. If you need a client and server configuration example see the samples. Additionally I think that something is not working correctly with your build system, since making configurations changes, e.g. enabling |
Beta Was this translation helpful? Give feedback.
-
|
Here you go a minimal example for a client: #include "oscore.h"
#include "oscore_test_vectors.h"
enum err nvm_write_ssn(const struct nvm_key_t *nvm_key, uint64_t ssn)
{
(void)nvm_key;
(void)ssn;
PRINT_MSG("NVM write mock\n");
return ok;
}
enum err nvm_read_ssn(const struct nvm_key_t *nvm_key, uint64_t *ssn)
{
(void)nvm_key;
PRINT_MSG("NVM read mock\n");
*ssn = 0;
return ok;
}
int main()
{
enum err r;
uint8_t buf_oscore[256];
uint32_t buf_oscore_len = sizeof(buf_oscore);
uint8_t buf_coap[256];
uint32_t buf_coap_len = sizeof(buf_coap);
struct oscore_init_params params = {
.master_secret.len = T1__MASTER_SECRET_LEN,
.master_secret.ptr = (uint8_t *)T1__MASTER_SECRET,
.sender_id.len = T1__SENDER_ID_LEN,
.sender_id.ptr = (uint8_t *)T1__SENDER_ID,
.recipient_id.len = T1__RECIPIENT_ID_LEN,
.recipient_id.ptr = (uint8_t *)T1__RECIPIENT_ID,
.id_context.len = T1__ID_CONTEXT_LEN,
.id_context.ptr = (uint8_t *)T1__ID_CONTEXT,
.master_salt.len = T1__MASTER_SALT_LEN,
.master_salt.ptr = (uint8_t *)T1__MASTER_SALT,
OSCORE_AES_CCM_16_64_128,
OSCORE_SHA_256,
false, // the SSN will be restored from NVM.
};
struct context c_client;
r = oscore_context_init(¶ms, &c_client);
if (r != ok) {
printf("Error during establishing an OSCORE security context!\n");
}
//ecrypt the request
r = coap2oscore((uint8_t *)T1__COAP_REQ, T1__COAP_REQ_LEN, buf_oscore,
&buf_oscore_len, &c_client);
if (r != ok) {
printf("Error in coap2oscore (Error code %d)!\n", r);
}
//decrypt the response
r = oscore2coap((uint8_t *)T1__OSCORE_RESP, T1__OSCORE_RESP_LEN,
buf_coap, &buf_coap_len, &c_client);
if (r != ok) {
printf("Error in oscore2coap (Error code %d)!\n", r);
}
}Note that when you are using OSCORE (without EDHOC) and do not have a fresh key after the device has rebooted the sender sequence number (SSN) needs to be cached on the NVM of the device. This is in order to prevent nonce reuse attacks. You need to provide an implementation of |
Beta Was this translation helpful? Give feedback.
-
|
This is my log when executing the code above: It produces the expected result. You can test it by your self by creating a Do you have |
Beta Was this translation helpful? Give feedback.

Uh oh!
There was an error while loading. Please reload this page.
-
Hello,
currently I try to implement uoscore and it fails at the first step of the test cases. I simply copied the test vectors and tried to run them through the initialization to get the estimated encrypted package. Afterwards I want to reverse the process to read the original packet (T1__COAP_REQ) again. In detail, this is what I do:
`
/Test vector C1.1: Key derivation with Master Salt/
const uint8_t T1__MASTER_SECRET[16] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
0x0d, 0x0e, 0x0f, 0x10 };
uint8_t T1__MASTER_SECRET_LEN = sizeof(T1__MASTER_SECRET);
const uint8_t *T1__SENDER_ID = NULL;
uint8_t T1__SENDER_ID_LEN = 0;
const uint8_t T1__RECIPIENT_ID[1] = { 0x01 };
uint8_t T1__RECIPIENT_ID_LEN = sizeof(T1__RECIPIENT_ID);
const uint8_t T1__MASTER_SALT[8] = { 0x9e, 0x7c, 0xa9, 0x22,
0x23, 0x78, 0x63, 0x40 };
uint8_t T1__MASTER_SALT_LEN = sizeof(T1__MASTER_SALT);
const uint8_t *T1__ID_CONTEXT = NULL;
uint8_t T1__ID_CONTEXT_LEN = 0;
/*Test vector C4: Generating a OSCORE Packet with key material form test vector C.1 */
const uint8_t T1__COAP_REQ[] = { 0x44, 0x01, 0x5d, 0x1f, 0x00, 0x00, 0x39, 0x74,
0x39, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f,
0x73, 0x74, 0x83, 0x74, 0x76, 0x31 };
uint16_t T1__COAP_REQ_LEN = sizeof(T1__COAP_REQ);
/Expected result/
const uint8_t T1__SENDER_KEY[] = { 0xf0, 0x91, 0x0e, 0xd7, 0x29, 0x5e,
0x6a, 0xd4, 0xb5, 0x4f, 0xc7, 0x93,
0x15, 0x43, 0x02, 0xff };
uint8_t T1__SENDER_KEY_LEN = sizeof(T1__SENDER_KEY);
const uint8_t T1__RECIPIENT_KEY[] = { 0xff, 0xb1, 0x4e, 0x09, 0x3c, 0x94,
0xc9, 0xca, 0xc9, 0x47, 0x16, 0x48,
0xb4, 0xf9, 0x87, 0x10 };
uint8_t T1__RECIPIENT_KEY_LEN = sizeof(T1__RECIPIENT_KEY);
const uint8_t T1__COMMON_IV[] = { 0x46, 0x22, 0xd4, 0xdd, 0x6d, 0x94, 0x41,
0x68, 0xee, 0xfb, 0x54, 0x98, 0x7c };
uint8_t T1__COMMON_IV_LEN = sizeof(T1__COMMON_IV);
const uint8_t T1__OSCORE_REQ[] = { 0x44, 0x02, 0x5d, 0x1f, 0x00, 0x00, 0x39,
0x74, 0x39, 0x6c, 0x6f, 0x63, 0x61, 0x6c,
0x68, 0x6f, 0x73, 0x74, 0x62, 0x09, 0x14,
0xff, 0x61, 0x2f, 0x10, 0x92, 0xf1, 0x77,
0x6f, 0x1c, 0x16, 0x68, 0xb3, 0x82, 0x5e };
uint8_t T1__OSCORE_REQ_LEN = sizeof(T1__OSCORE_REQ);
/test the response/
/Values from Appendix C7/
const uint8_t T1__OSCORE_RESP[] = { 0x64, 0x44, 0x5D, 0x1F, 0x00, 0x00, 0x39,
0x74, 0x90, 0xFF, 0xDB, 0xAA, 0xD1, 0xE9,
0xA7, 0xE7, 0xB2, 0xA8, 0x13, 0xD3, 0xC3,
0x15, 0x24, 0x37, 0x83, 0x03, 0xCD, 0xAF,
0xAE, 0x11, 0x91, 0x06 };
uint8_t T1__OSCORE_RESP_LEN = sizeof(T1__OSCORE_RESP);
const uint8_t T1__COAP_RESPONSE[] = {
0x64, 0x45, 0x5d, 0x1f, 0x00, 0x00, 0x39, 0x74, 0xff, 0x48, 0x65,
0x6c, 0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x21
};
uint8_t T1__COAP_RESPONSE_LEN = sizeof(T1__COAP_RESPONSE);
enum reverse_t { NORMAL, REVERSED };
enum freshness_t { FRESH, RESTORED };
struct byte_array sender = { .ptr = (uint8_t *)T1__SENDER_ID,
.len = T1__SENDER_ID_LEN };
struct byte_array recipient = { .ptr = (uint8_t *)T1__RECIPIENT_ID,
.len = T1__RECIPIENT_ID_LEN };
enum reverse_t is_reversed = NORMAL;
enum freshness_t is_fresh = FRESH;
struct oscore_init_params params = {
.master_secret.ptr = (uint8_t *)T1__MASTER_SECRET,
.master_secret.len = T1__MASTER_SECRET_LEN,
.sender_id = (is_reversed == NORMAL) ? sender : recipient,
.recipient_id = (is_reversed == NORMAL) ? recipient : sender,
.master_salt.ptr = (uint8_t *)T1__MASTER_SALT,
.master_salt.len = T1__MASTER_SALT_LEN,
.id_context.ptr = (uint8_t *)T1__ID_CONTEXT,
.id_context.len = T1__ID_CONTEXT_LEN,
.aead_alg = OSCORE_AES_CCM_16_64_128,
.hkdf = OSCORE_SHA_256,
.fresh_master_secret_salt = (is_fresh == FRESH),
};
uint8_t buf_o_coap[256];
uint32_t buf_o_coap_len = sizeof(buf_o_coap);
uint8_t buf_oscore[256];
uint32_t buf_oscore_len = sizeof(buf_oscore);
oscore_context_init(¶ms, &c_client);
printf("Key Sender: \n");
print_hex_string(c_client.sc.sender_key.ptr, 16);
printf("\n");
coap2oscore((uint8_t *)T1__COAP_REQ, T1__COAP_REQ_LEN,
(uint8_t *)&buf_oscore, &buf_oscore_len, &c_client);
printf("Created Oscore packet: %s\n", &buf_oscore);
print_hex_string(buf_oscore, T1__OSCORE_REQ_LEN);
`
Somehow it returns partly the correct response, but the encryption fails. The first part of the OSCORE packet, the not encrypted part is correct, but the Byte before the FF indicator and the part afterwards do not match. I integrated the .c and .h files of the uoscore-uedhoc project into my own project. Is this problem known, or is it wrong initialization / usage of the functions?
Best,
Robert
Beta Was this translation helpful? Give feedback.
All reactions