uint16_t len;
} protocomm_security_pop_t;
+typedef void * protocomm_security_handle_t;
+
/**
* @brief Protocomm security object structure.
*
* Function for initializing/allocating security
* infrastructure
*/
- esp_err_t (*init)();
+ esp_err_t (*init)(protocomm_security_handle_t *handle);
/**
* Function for deallocating security infrastructure
*/
- esp_err_t (*cleanup)();
+ esp_err_t (*cleanup)(protocomm_security_handle_t handle);
/**
* Starts new secure transport session with specified ID
*/
- esp_err_t (*new_transport_session)(uint32_t session_id);
+ esp_err_t (*new_transport_session)(protocomm_security_handle_t handle,
+ uint32_t session_id);
/**
* Closes a secure transport session with specified ID
*/
- esp_err_t (*close_transport_session)(uint32_t session_id);
+ esp_err_t (*close_transport_session)(protocomm_security_handle_t handle,
+ uint32_t session_id);
/**
* Handler function for authenticating connection
* request and establishing secure session
*/
- esp_err_t (*security_req_handler)(const protocomm_security_pop_t *pop,
+ esp_err_t (*security_req_handler)(protocomm_security_handle_t handle,
+ const protocomm_security_pop_t *pop,
uint32_t session_id,
const uint8_t *inbuf, ssize_t inlen,
uint8_t **outbuf, ssize_t *outlen,
/**
* Function which implements the encryption algorithm
*/
- esp_err_t (*encrypt)(uint32_t session_id,
+ esp_err_t (*encrypt)(protocomm_security_handle_t handle,
+ uint32_t session_id,
const uint8_t *inbuf, ssize_t inlen,
uint8_t *outbuf, ssize_t *outlen);
/**
* Function which implements the decryption algorithm
*/
- esp_err_t (*decrypt)(uint32_t session_id,
+ esp_err_t (*decrypt)(protocomm_security_handle_t handle,
+ uint32_t session_id,
const uint8_t *inbuf, ssize_t inlen,
uint8_t *outbuf, ssize_t *outlen);
} protocomm_security_t;
/* Free memory allocated to security */
if (pc->sec && pc->sec->cleanup) {
- pc->sec->cleanup();
+ pc->sec->cleanup(pc->sec_inst);
}
if (pc->pop) {
free(pc->pop);
}
ssize_t dec_inbuf_len = inlen;
- ret = pc->sec->decrypt(session_id, inbuf, inlen, dec_inbuf, &dec_inbuf_len);
+ ret = pc->sec->decrypt(pc->sec_inst, session_id, inbuf, inlen, dec_inbuf, &dec_inbuf_len);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Decryption of response failed for endpoint %s", ep_name);
free(dec_inbuf);
}
ssize_t enc_resp_len = plaintext_resp_len;
- ret = pc->sec->encrypt(session_id, plaintext_resp, plaintext_resp_len,
+ ret = pc->sec->encrypt(pc->sec_inst, session_id, plaintext_resp, plaintext_resp_len,
enc_resp, &enc_resp_len);
if (ret != ESP_OK) {
protocomm_t *pc = (protocomm_t *) priv_data;
if (pc->sec && pc->sec->security_req_handler) {
- return pc->sec->security_req_handler(pc->pop, session_id,
+ return pc->sec->security_req_handler(pc->sec_inst,
+ pc->pop, session_id,
inbuf, inlen,
outbuf, outlen,
priv_data);
}
if (sec->init) {
- ret = sec->init();
+ ret = sec->init(&pc->sec_inst);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Error initializing security");
protocomm_remove_endpoint(pc, ep_name);
if (pc->pop == NULL) {
ESP_LOGE(TAG, "Error allocating Proof of Possession");
if (pc->sec && pc->sec->cleanup) {
- pc->sec->cleanup();
+ pc->sec->cleanup(pc->sec_inst);
+ pc->sec_inst = NULL;
pc->sec = NULL;
}
}
if (pc->sec && pc->sec->cleanup) {
- pc->sec->cleanup();
+ pc->sec->cleanup(pc->sec_inst);
+ pc->sec_inst = NULL;
pc->sec = NULL;
}
size_t nc_off;
} session_t;
-static session_t *cur_session;
-
static void flip_endian(uint8_t *data, size_t len)
{
uint8_t swp_buf;
ESP_LOG_BUFFER_HEX_LEVEL(TAG, buf, len, ESP_LOG_DEBUG);
}
-static esp_err_t handle_session_command1(uint32_t session_id,
+static esp_err_t handle_session_command1(session_t *cur_session,
+ uint32_t session_id,
SessionData *req, SessionData *resp)
{
ESP_LOGD(TAG, "Request to handle setup1_command");
return ESP_OK;
}
-static esp_err_t handle_session_command0(uint32_t session_id,
+static esp_err_t handle_session_command0(session_t *cur_session,
+ uint32_t session_id,
SessionData *req, SessionData *resp,
const protocomm_security_pop_t *pop)
{
return ret;
}
-static esp_err_t sec1_session_setup(uint32_t session_id,
+static esp_err_t sec1_session_setup(session_t *cur_session,
+ uint32_t session_id,
SessionData *req, SessionData *resp,
const protocomm_security_pop_t *pop)
{
Sec1Payload *in = (Sec1Payload *) req->sec1;
esp_err_t ret;
- if (!cur_session) {
- ESP_LOGE(TAG, "Invalid session context data");
- return ESP_ERR_INVALID_ARG;
- }
-
- if (session_id != cur_session->id) {
- ESP_LOGE(TAG, "Invalid session ID : %d (expected %d)", session_id, cur_session->id);
- return ESP_ERR_INVALID_STATE;
- }
-
if (!in) {
ESP_LOGE(TAG, "Empty session data");
return ESP_ERR_INVALID_ARG;
switch (in->msg) {
case SEC1_MSG_TYPE__Session_Command0:
- ret = handle_session_command0(session_id, req, resp, pop);
+ ret = handle_session_command0(cur_session, session_id, req, resp, pop);
break;
case SEC1_MSG_TYPE__Session_Command1:
- ret = handle_session_command1(session_id, req, resp);
+ ret = handle_session_command1(cur_session, session_id, req, resp);
break;
default:
ESP_LOGE(TAG, "Invalid security message type");
}
-static void sec1_session_setup_cleanup(uint32_t session_id, SessionData *resp)
+static void sec1_session_setup_cleanup(session_t *cur_session, uint32_t session_id, SessionData *resp)
{
Sec1Payload *out = resp->sec1;
return;
}
-static esp_err_t sec1_close_session(uint32_t session_id)
+static esp_err_t sec1_close_session(protocomm_security_handle_t handle, uint32_t session_id)
{
+ session_t *cur_session = (session_t *) handle;
+ if (!cur_session) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
if (!cur_session || cur_session->id != session_id) {
ESP_LOGE(TAG, "Attempt to close invalid session");
- return ESP_ERR_INVALID_ARG;
+ return ESP_ERR_INVALID_STATE;
}
if (cur_session->state == SESSION_STATE_DONE) {
mbedtls_aes_free(&cur_session->ctx_aes);
}
- bzero(cur_session, sizeof(session_t));
- free(cur_session);
- cur_session = NULL;
+ memset(cur_session, 0, sizeof(session_t));
+ cur_session->id = -1;
return ESP_OK;
}
-static esp_err_t sec1_new_session(uint32_t session_id)
+static esp_err_t sec1_new_session(protocomm_security_handle_t handle, uint32_t session_id)
{
- if (cur_session) {
- /* Only one session is allowed at a time */
- ESP_LOGE(TAG, "Closing old session with id %u", cur_session->id);
- sec1_close_session(cur_session->id);
+ session_t *cur_session = (session_t *) handle;
+ if (!cur_session) {
+ return ESP_ERR_INVALID_ARG;
}
- cur_session = (session_t *) calloc(1, sizeof(session_t));
- if (!cur_session) {
- ESP_LOGE(TAG, "Error allocating session structure");
- return ESP_ERR_NO_MEM;
+ if (cur_session->id != -1) {
+ /* Only one session is allowed at a time */
+ ESP_LOGE(TAG, "Closing old session with id %u", cur_session->id);
+ sec1_close_session(cur_session, session_id);
}
cur_session->id = session_id;
return ESP_OK;
}
-static esp_err_t sec1_init()
+static esp_err_t sec1_init(protocomm_security_handle_t *handle)
{
+ if (!handle) {
+ return ESP_ERR_INVALID_ARG;
+ }
+ session_t *cur_session = (session_t *) calloc(1, sizeof(session_t));
+ if (!cur_session) {
+ ESP_LOGE(TAG, "Error allocating new session");
+ return ESP_ERR_NO_MEM;
+ }
+ cur_session->id = -1;
+ *handle = (protocomm_security_handle_t) cur_session;
return ESP_OK;
}
-static esp_err_t sec1_cleanup()
+static esp_err_t sec1_cleanup(protocomm_security_handle_t handle)
{
+ session_t *cur_session = (session_t *) handle;
if (cur_session) {
- ESP_LOGD(TAG, "Closing current session with id %u", cur_session->id);
- sec1_close_session(cur_session->id);
+ sec1_close_session(handle, cur_session->id);
}
+ free(handle);
return ESP_OK;
}
-static esp_err_t sec1_decrypt(uint32_t session_id,
+static esp_err_t sec1_decrypt(protocomm_security_handle_t handle,
+ uint32_t session_id,
const uint8_t *inbuf, ssize_t inlen,
uint8_t *outbuf, ssize_t *outlen)
{
+ session_t *cur_session = (session_t *) handle;
+ if (!cur_session) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
if (*outlen < inlen) {
return ESP_ERR_INVALID_ARG;
}
return ESP_OK;
}
-static esp_err_t sec1_req_handler(const protocomm_security_pop_t *pop, uint32_t session_id,
+static esp_err_t sec1_req_handler(protocomm_security_handle_t handle,
+ const protocomm_security_pop_t *pop,
+ uint32_t session_id,
const uint8_t *inbuf, ssize_t inlen,
uint8_t **outbuf, ssize_t *outlen,
void *priv_data)
{
+ session_t *cur_session = (session_t *) handle;
+ if (!cur_session) {
+ ESP_LOGE(TAG, "Invalid session context data");
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ if (session_id != cur_session->id) {
+ ESP_LOGE(TAG, "Invalid session ID : %d (expected %d)", session_id, cur_session->id);
+ return ESP_ERR_INVALID_STATE;
+ }
+
SessionData *req;
SessionData resp;
esp_err_t ret;
}
session_data__init(&resp);
- ret = sec1_session_setup(session_id, req, &resp, pop);
+ ret = sec1_session_setup(cur_session, session_id, req, &resp, pop);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Session setup error %d", ret);
session_data__free_unpacked(req, NULL);
}
session_data__pack(&resp, *outbuf);
- sec1_session_setup_cleanup(session_id, &resp);
+ sec1_session_setup_cleanup(cur_session, session_id, &resp);
return ESP_OK;
}