Commit 26ac2620 authored by Jonas Hundseder's avatar Jonas Hundseder
Browse files

Final Version, all functions complete, code and style structure

parent 2bb36c74
/**
* @file ownCMAC.h
* @author Jonas Hundseder (jonas.hundseder@hs-augsburg.de)
* @brief Header for CMAC session
* @version 1.0
* @date 2021-11-24
*
* @copyright Copyright (c) 2021
*
* Company: Hochschule Augsburg
*
* Header containing functions to operate a one-key CMAC session to
* authentification server or client
*
*/
#ifndef OWNCMAC_H
#define OWNCMAC_H
//____includes_____________________________________________________________________
#include <mbed.h>
//____defines______________________________________________________________________
#define SMI_CMAC_LENGTH 16
//____declaration__________________________________________________________________
/**
* @brief init CMAC context and add key to CMAC session
* @param aes_key key to initialize CMAC session
*/
void cmac_init(uint8_t aes_key[16]);
/**
* @brief get AES CTR encoded snippet data, calculate CMAC and
* add CMAC to snippet data. Ready to send to server
*
* @param data_enc input encoded snippet data of length \c 8 bytes
* @param data_cmac output encoded snippet data with calculatet CMAC, must have a length of \c 24 bytes
*/
void create_data_snippets_cmac(uint8_t data_enc[8], uint8_t data_cmac[24]);
/**
* @brief get solved data encoded with AES CTR, calculate CMAC and
* add CMAC to solved data. Ready to send to server
*
* @param data_enc input AES CTR encoded solved puzzel data, must have a length of \c 71 bytes
* @param data_cmac output encoded solved puzzel with calculated CMAC, must have a length of \c 87 bytes
*/
void create_data_solve_cmac(uint8_t data_enc[71], uint8_t data_cmac[87]);
/**
* @brief function check if CMAC of \c 16 bytes at the end of data is correct or not
*
* @param data data with CMAC, which has to be checked
* @param length length of data
* @return int return \c 0 if CMAC is correct, return \c -1 if not
*/
int check_cmac(uint8_t *data, size_t length);
#endif // OWNCMAC_H
\ No newline at end of file
......@@ -39,4 +39,10 @@ void get_solve_snippets(void);
*/
void get_solve_snippets_aesctr(void);
/**
* @brief
*
*/
void get_solve_snippets_aesctr_cmac(uint8_t aes_key[16]);
#endif // SNIPPETS_H
\ No newline at end of file
......@@ -62,6 +62,22 @@ HttpRequest create_request_aesctr_solve(void);
*/
HttpRequest create_request_aesctr_getsnippet(void);
/**
* @brief Create a request aesctr cmac getsnippet object to get snippets from server
* in a AES CTR CMAC session
*
* @return HttpRequest return request object
*/
HttpRequest create_request_aesctr_cmac_getsnippet(void);
/**
* @brief Create a request aesctr cmac solve object to send solved data to server
* in a AES CTR CMAC session
*
* @return HttpRequest return request object
*/
HttpRequest create_request_aesctr_cmac_solve(void);
/**
* @brief Create a request public key object to get the public modulus from server
*
......@@ -79,7 +95,7 @@ HttpRequest create_request_client_aes(void);
/**
* @brief Create a request test exKey object to send random data encoded with final AES
* key to server and get encoded with AES key from server (same data send and get)
* key to server and get encoded with AES key from server (same data send and get)
*
* @return HttpRequest return request object
*/
......@@ -104,13 +120,8 @@ void send_request_solve(HttpRequest *request, uint8_t *uid, uint8_t *hash_equal_
* @param request generated request with \p create_request_aesctr_solve
* @param uid pointer to Tag UID
* @param hash_equal_index pointer to hash_equal_index array, with correct order of snippet index
* @param aesctx actual context to encryped and decryped data to send
*/
void send_request_aesctr_solve(
HttpRequest *request,
uint8_t *uid,
uint8_t *hash_equal_index,
mbedtls_aes_context *aesctx);
void send_request_aesctr_solve(HttpRequest *request, uint8_t *uid, uint8_t *hash_equal_index);
/**
* @brief send generated request getsnippets with data to server
......@@ -133,12 +144,32 @@ HttpResponse *send_request_snippet(HttpRequest request, uint8_t *bufferId, uint8
* @param request generated request with \p create_request_aesctr_getsnippets
* @param bufferId buffer for Tag ID
* @param bufferIn buffer for index number
* @param aesctx actual context to encryped and decryped data to send
* @return HttpResponse* pointer to response structure, containing response data (hash snippets enc) send
* @return HttpResponse* pointer to response structure, containing response data (hash snippets enc)
* by server
*/
HttpResponse *
send_request_aesctr_snippet(HttpRequest request, uint8_t *bufferId, uint8_t *bufferIn, mbedtls_aes_context *aesctx);
HttpResponse *send_request_aesctr_snippet(HttpRequest request, uint8_t *bufferId, uint8_t *bufferIn);
/**
* @brief send generated request getsnippets with data to server
* add to encoded snippet message CMAC data to get snippet data in a CMAC session
*
* @param request generated request with \p create_request_aesctr_cmac_getsnippets
* @param bufferId buffer for Tag ID
* @param bufferIn buffer for index number
* @return HttpResponse* pointer to response structure, containing response data (hash snippet enc with
* CMAC)
*/
HttpResponse *send_request_aesctr_cmac_snippet(HttpRequest request, uint8_t *bufferId, uint8_t *bufferIn);
/**
* @brief send generated request with data to server and get the response data
* need to be send to solve puzzel in CMAC session
* @param request generated request with \p create_request_aesctr_cmac_solve
* @param uid Tag ID
* @param hash_equal_index array of solved puzzel. Index of hash values in right order
* @param aes_key
*/
void send_request_aesctr_cmac_solve(HttpRequest *request, uint8_t *uid, uint8_t *hash_equal_index);
/**
* @brief send generated request with data to server and get the response data
......
......@@ -37,7 +37,9 @@ int main(void)
extern uint8_t buffer_modulus_client[256];
// array for final aes key after exchange with server
uint8_t aes_key[16];
uint8_t aes_key[16] = { 0 };
int decision = 0;
// call functions in correct order
......@@ -63,23 +65,24 @@ int main(void)
get_final_aes_key(aes_key);
// test_aesKey(aes_key);
aes_ctr_init(aes_key);
get_solve_snippets_aesctr();
// mbedtls_aes_free(&aesctx);
// mbedtls_aes_init(&aesctx);
// mbedtls_aes_setkey_enc(&aesctx,aes_key,128);
// nc_off = 0;
// memset(nonce_counter,0,sizeof(nonce_counter));
// memset(stream_block,0,sizeof(stream_block));
// HttpRequest aes_ctr_solve = create_request_aesctr_getsnippet();
test_aesKey(aes_key);
printf("Press 1 for AES CTR session, press 2 for AES CTR CMAC session \n");
scanf("%d", &decision);
switch (decision)
{
case 1:
printf("Start AES CTR session: \n");
get_solve_snippets_aesctr();
break;
case 2:
printf("Start CMAC session: \n");
get_solve_snippets_aesctr_cmac(aes_key);
break;
}
free(index_hash);
......
......@@ -52,7 +52,7 @@ void wait_for_tag()
{
bool result = false;
//printf("Wait for Tag\n");
// printf("Wait for Tag\n");
INFO("Wait for Tag\n");
while (result != true)
......@@ -74,11 +74,11 @@ void get_UID()
bool result = nfc.PICC_ReadCardSerial();
if (result == true)
{
{
memcpy(bufferID, nfc.uid.uidByte, SMI_TAGID_LENGTH);
DEBUGARRAY(bufferID, sizeof(bufferID),"TagID: ");
DEBUGARRAY(bufferID, sizeof(bufferID), "TagID: ");
}
else
{
......@@ -192,7 +192,7 @@ void create_data_snippets(uint8_t *data, uint8_t *bufferId, uint8_t *bufferIn)
memcpy(data + SMI_TAGID_LENGTH, bufferIn, (SMI_TAGIN_LENGTH));
DEBUGARRAY(data, 8,"snippets data: ");
DEBUGARRAY(data, 8, "snippets data: ");
return;
}
\ No newline at end of file
......@@ -167,7 +167,7 @@ void get_final_aes_key(uint8_t aes_key[16])
aes_key[i] = server_half_aes_key[i] ^ client_half_aes_key[i];
}
INFOARRAY(aes_key,16,"AES Key final: ");
INFOARRAY(aes_key, 16, "AES Key final: ");
return;
}
......@@ -209,9 +209,6 @@ void test_aesKey(uint8_t aes_key[16])
uint8_t aes_test_final[32] = { 0 };
uint8_t aes_test_server_enc[32] = { 0 };
// int aesctx wit key
aes_ctr_init(aes_key);
// encode data with AES Key
MBED_ASSERT(mbedtls_aes_crypt_ctr(&aesctx, 32, &nc_off, nonce_counter, stream_block, aes_test, aes_test_enc) == 0);
......@@ -228,12 +225,24 @@ void test_aesKey(uint8_t aes_key[16])
0);
// print final result of data exchange to debug
DEBUGARRAY(aes_test_final,sizeof(aes_test_final),"final result aes test: ");
DEBUGARRAY(aes_test_final, sizeof(aes_test_final), "final result aes test: ");
// check if aes_test array and aes test result array are the same. success if equal otherwise exit programm
for (int i = 0; i < 32; ++i)
{
if (aes_test[i] != aes_test_final[i])
{
ERROR("AES Key exchange failed!! exit!\n");
exit(0);
}
}
INFO("AES Key exchange successfull completed!\n");
return;
}
// release memory aesctx
// release memory AES context
void free_aes(void)
{
mbedtls_aes_free(&aesctx);
......
/**
* @file ownCMAC.cpp
* @author Jonas Hundseder (jonas.hundseder@hs-augsburg.de)
* @brief source file for AES CTR encrypt session
* @version 1.0
* @date 2021-11-24
*
* @copyright Copyright (c) 2021
*
* Company: Hochschule Augsburg
*
*/
//____includes_____________________________________________________________________
#include "ownCMAC.h"
#include <cmac.h>
#include <logger.h>
//____defines______________________________________________________________________
//____globals______________________________________________________________________
// CMAC context to operate CMAC session
mbedtls_cipher_context_t cmacctx;
//____implementation________________________________________________________________
/**
* init CMAC context with given Key
*
*/
void cmac_init(uint8_t aes_key[16])
{
// init CMAC context
MBED_ASSERT(mbedtls_cipher_setup(&cmacctx, mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB)) == 0);
// set CMAC key
MBED_ASSERT(mbedtls_cipher_cmac_starts(&cmacctx, aes_key, 128) == 0);
return;
}
/**
* create CMAC with initialized CMAC context from given AES CTR encoded snippet data
*
*/
void create_data_snippets_cmac(uint8_t data_enc[8], uint8_t data_cmac[24])
{
uint8_t cmac_output[SMI_CMAC_LENGTH] = { 0 };
// feeds encoded snippet data in ongoing CMAC computation
MBED_ASSERT(mbedtls_cipher_cmac_update(&cmacctx, data_enc, 8) == 0);
// output CMAC data from encoded data
MBED_ASSERT(mbedtls_cipher_cmac_finish(&cmacctx, cmac_output) == 0);
INFOARRAY(cmac_output, 16, "CMAC data from client: ");
// add CMAC data to snippet data
memcpy(data_cmac, data_enc, 8);
memcpy(data_cmac + 8, cmac_output, SMI_CMAC_LENGTH);
DEBUGARRAY(data_cmac, 24, "data snippet enc with cmac data: ");
return;
}
/**
* reate CMAC with initialized CMAC context from encoded solved puzzel data
*
*/
void create_data_solve_cmac(uint8_t data_enc[71], uint8_t data_cmac[87])
{
uint8_t cmac_output[16] = { 0 };
// feeds encoded puzzel solved data to ongoing CMAC computation
MBED_ASSERT(mbedtls_cipher_cmac_update(&cmacctx, data_enc, 71) == 0);
// output CMAC from puzzel solved data
MBED_ASSERT(mbedtls_cipher_cmac_finish(&cmacctx, cmac_output) == 0);
// add CMAC data to puzzel solved data
memcpy(data_cmac, data_enc, 71);
memcpy(data_cmac + 71, cmac_output, SMI_CMAC_LENGTH);
return;
}
/**
* check if CMAC of given data is correct or not
* data has to include CMAC at end of memory (length of \c 16 bytes)
*
*/
int check_cmac(uint8_t *data, size_t length)
{
uint8_t cmac_data[16] = { 0 };
uint8_t cmac_output[16] = { 0 };
size_t payload_length = length - SMI_CMAC_LENGTH;
// DEBUGARRAY(data,payload_length, "Payload data from server" );
// extract CMAC out of data
memcpy(cmac_data, (data + payload_length), SMI_CMAC_LENGTH);
INFOARRAY(cmac_data, SMI_CMAC_LENGTH, "CMAC data from server: ");
// calculate CMAC of given payload from data
MBED_ASSERT(mbedtls_cipher_cmac_update(&cmacctx, data, payload_length) == 0);
MBED_ASSERT(mbedtls_cipher_cmac_finish(&cmacctx, cmac_output) == 0);
INFOARRAY(cmac_output, SMI_CMAC_LENGTH, "CMAC data calculated: ");
// compare CMAC from data with own calculated CMAC
for (int i = 0; i < 16; ++i)
{
if (cmac_data[i] != cmac_output[i])
{
ERROR("CMAC is not correct!\n");
return -1;
}
}
return 0;
}
\ No newline at end of file
......@@ -75,7 +75,7 @@ void create_client_modulus()
// transfer data typ mbedtls_mpi into binary uint8_t array
MBED_ASSERT(mbedtls_mpi_write_binary(&rsactx_client.N, buffer_modulus_client, 256) == 0);
DEBUGARRAY(buffer_modulus_client, sizeof(buffer_modulus_client),"Client Public Key: ");
DEBUGARRAY(buffer_modulus_client, sizeof(buffer_modulus_client), "Client Public Key: ");
trng_free(&rngctx);
......@@ -101,7 +101,7 @@ void get_modulus_server(void)
// send request to server, get public key server
send_request_public_key(&request_public_key, public_key_server);
INFOARRAY(public_key_server, sizeof(public_key_server),"public Modulus from server: ");
INFOARRAY(public_key_server, sizeof(public_key_server), "public Modulus from server: ");
// import key into RSA context server with public exponent
MBED_ASSERT(
......
......@@ -16,10 +16,11 @@
#include "snippets.h"
#include "nfc.h"
#include "ownAes.h"
#include "ownCMAC.h"
#include "printHex.h"
#include "wifi.h"
#include <sha256.h>
#include <logger.h>
#include <sha256.h>
//____defines______________________________________________________________________
......@@ -35,10 +36,12 @@ uint8_t hash_snippet[SNIPPET_HASH_LENGTH] = { 0 };
// buffer for Index value of each hash
uint8_t hash_equal_index[64] = { 0 };
uint8_t snippet_data_enc[4500] = { 0 };
//____implementation_______________________________________________________________
/**
* send request for each snippet (64 times), to get value for each snippet back
* send request for each snippet (64 times), to get value for each snippet from server
* calculate hash value of each snippet value
* solve puzzel
* send data from solve puzzel back to server
......@@ -63,6 +66,8 @@ void get_solve_snippets(void)
printfhex(hash_snippet, SNIPPET_HASH_LENGTH);
// memset(hash_equal_index,0,64);
// find in hash table (data from Tag) same hash value, save snippet number (snp) into hash_equal_index at place
// index_hash from equal hash
for (int ind = 0; ind < 64; ++ind)
......@@ -98,20 +103,18 @@ void get_solve_snippets_aesctr(void)
extern uint8_t bufferID[SMI_TAGID_LENGTH + 1];
extern uint8_t block[64][SMI_SHORT_HASH_LENGTH];
extern uint8_t *index_hash;
extern mbedtls_aes_context aesctx;
HttpResponse *response;
uint8_t snippet_dec[SNIPPET_DATA_LENGTH] = { 0 };
for (uint8_t snp = 0; snp < 64; ++snp)
{
// send and create request for each snippet but encoded wit AES CTR
response = send_request_aesctr_snippet(create_request_aesctr_getsnippet(), bufferID, &snp, &aesctx);
// send and create request for each snippet encoded with AES CTR
response = send_request_aesctr_snippet(create_request_aesctr_getsnippet(), bufferID, &snp);
// decode snippet data from server
aes_crypt_ctr(SNIPPET_DATA_LENGTH, (uint8_t *)response->get_body(), snippet_dec);
aes_crypt_ctr(response->get_body_length(), (uint8_t *)response->get_body(), snippet_data_enc);
// calculate hash value of snippet data with SHA256 algorithm
MBED_ASSERT(mbedtls_sha256_ret(snippet_dec, sizeof(snippet_dec), hash_snippet, 0) == 0);
MBED_ASSERT(mbedtls_sha256_ret(snippet_data_enc, response->get_body_length(), hash_snippet, 0) == 0);
INFOARRAY(hash_snippet, SNIPPET_HASH_LENGTH, "Hash-Wert snippet: ");
......@@ -134,5 +137,72 @@ void get_solve_snippets_aesctr(void)
HttpRequest aesctr_solve = create_request_aesctr_solve();
// send encoded data solve to server
send_request_aesctr_solve(&aesctr_solve, bufferID, hash_equal_index, &aesctx);
send_request_aesctr_solve(&aesctr_solve, bufferID, hash_equal_index);
}
/**
* send request for each snippet (64 times), to get value for each snippet from server
* encode snippet data with AES CTR and add CMAC to snippet data
* check CMAC from response data and encode server data with AES CTR session
* calculate hash value of each snippet value
* solve puzzel
* encode solved data with AES CTR and add CMAC to data, send solve puzzel back to server
*
*/
void get_solve_snippets_aesctr_cmac(uint8_t aes_key[16])
{
extern uint8_t bufferID[SMI_TAGID_LENGTH + 1];
extern uint8_t block[64][SMI_SHORT_HASH_LENGTH];
extern uint8_t *index_hash;
HttpResponse *response;
// init CMAC context for CMAC session
cmac_init(aes_key);
for (uint8_t snp = 0; snp < 64; ++snp)
{
// send and create request for each snippet encoded with AES CTR and add CMAC
response = send_request_aesctr_cmac_snippet(create_request_aesctr_cmac_getsnippet(), bufferID, &snp);
// DEBUGARRAY((uint8_t *) response->get_body(), response->get_body_length(), "snippet data with CMAC from
// server: ");
// check response encoded data CMAC for correctness
MBED_ASSERT(check_cmac((uint8_t *)response->get_body(), response->get_body_length()) == 0);
// decode snippet data from server
aes_crypt_ctr(
(response->get_body_length() - SMI_CMAC_LENGTH),
(uint8_t *)response->get_body(),
snippet_data_enc);
// calculate hash value of snippet data with SHA256 algorithm
MBED_ASSERT(
mbedtls_sha256_ret(snippet_data_enc, (response->get_body_length() - SMI_CMAC_LENGTH), hash_snippet, 0) ==
0);
INFOARRAY(hash_snippet, SNIPPET_HASH_LENGTH, "Hash-Wert snippet: ");
// find in hash table (data from Tag) same hash value, save snippet number (snp) into hash_equal_index at place
// index_hash from equal hash
for (int ind = 0; ind < 64; ++ind)
{
if (is_hash_equal(block[ind], hash_snippet))
{
hash_equal_index[index_hash[ind]] = snp;
printf("snippet_%d mit Index:%d\n", snp, *(index_hash + ind));
break;
}
}
}
// create request solve AES CMAC session puzzel
HttpRequest aesctr_cmac_solve = create_request_aesctr_cmac_solve();
// send encoded data solve to server in AES CMAC session
send_request_aesctr_cmac_solve(&aesctr_cmac_solve, bufferID, hash_equal_index);
return;
}
\ No newline at end of file
......@@ -16,15 +16,17 @@
#include "wifi.h"
#include "nfc.h"
#include "ownAes.h"
#include "ownCMAC.h"
#include "ownRsa.h"
#include "printHex.h"
#include <hal/trng_api.h>
#include <logger.h>
//____defines______________________________________________________________________
// check allocade memory was succesfull
// check if allocade memory was succesfull
#define CHECK_MALLOC(pointer) \
if ((pointer) == NULL) \
{ \
......@@ -144,6 +146,32 @@ HttpRequest create_request_test_exKey(void)
return request;
}
/**
* create request to get snippet in a AES CTR CMAC session with given http url
*/
HttpRequest create_request_aesctr_cmac_getsnippet(void)
{
WiFiInterface *wifi = WiFiInterface::get_default_instance();
HttpRequest request(wifi, HTTP_GET, "http://smi-server.stefan-hackenberg.de/crypto/aes_ctr_cmac/getsnippet");
return request;
}
/**
* create request to solve puzzel in a AES CTR CMAC session with given http url
*/
HttpRequest create_request_aesctr_cmac_solve(void)
{
WiFiInterface *wifi = WiFiInterface::get_default_instance();
HttpRequest request(wifi, HTTP_GET, "http://smi-server.stefan-hackenberg.de/crypto/aes_ctr_cmac/solve");
return request;
}
/**
* send request to solve puzzel with data containing snippts number in right index order
*
......@@ -172,11 +200,7 @@ void send_request_solve(HttpRequest *request, uint8_t *uid, uint8_t *hash_equal_
* send request to solve puzzel with data containing snippts number in right index order
* request data and response data encoded by this function and send to server in AES CTR session
*/
void send_request_aesctr_solve(
HttpRequest *request,
uint8_t *uid,
uint8_t *hash_equal_index,
mbedtls_aes_context *aesctx)
void send_request_aesctr_solve(HttpRequest *request, uint8_t *uid, uint8_t *hash_equal_index)
{
// allocate memory
uint8_t *data = (uint8 *)malloc(64 + 7);
......@@ -193,7 +217,7 @@ void send_request_aesctr_solve(
memcpy(data + 7, hash_equal_index, 64);
// encode given data to data_encoded
aes_crypt_ctr(sizeof(data), data, data_enc);