Exemple #1
0
static bool gzp_key_update(void)
{
    uint8_t tx_packet[GZP_CMD_KEY_UPDATE_PAYLOAD_LENGTH], rx_packet[GZP_MAX_ACK_PAYLOAD_LENGTH];

    // Send "prepare packet" to get session token to be used for key update
    tx_packet[0] = (uint8_t)GZP_CMD_KEY_UPDATE_PREPARE;

    // If packet was successfully sent AND a response packet was received
    if(gzp_tx_rx_transaction(tx_packet, GZP_CMD_KEY_UPDATE_PREPARE_PAYLOAD_LENGTH, rx_packet, NULL, GZP_DATA_PIPE) == GZP_TX_RX_SUCCESS)
    {
        if(rx_packet[0] == (uint8_t)GZP_CMD_KEY_UPDATE_PREPARE_RESP)
        {
            gzp_crypt_set_session_token(&rx_packet[GZP_CMD_KEY_UPDATE_PREPARE_RESP_SESSION_TOKEN]);

            // Build "key update" packet
            tx_packet[0] = (uint8_t)GZP_CMD_KEY_UPDATE;
            gzp_add_validation_id(&tx_packet[GZP_CMD_KEY_UPDATE_VALIDATION_ID]);
            gzp_random_numbers_generate(&tx_packet[GZP_CMD_KEY_UPDATE_NEW_KEY], GZP_DYN_KEY_LENGTH);
            gzp_crypt_set_dyn_key(&tx_packet[GZP_CMD_KEY_UPDATE_NEW_KEY]);

            // Encrypt "key update packet"
            gzp_crypt_select_key(GZP_KEY_EXCHANGE);
            gzp_crypt(&tx_packet[1], &tx_packet[1], GZP_CMD_KEY_UPDATE_PAYLOAD_LENGTH - 1);

            // Send "key update" packet
            if(gzp_tx_packet(tx_packet, GZP_CMD_KEY_UPDATE_PAYLOAD_LENGTH, GZP_DATA_PIPE))
            {
                return true;
            }
        }
    }

    return false;
}
Exemple #2
0
static void gzp_process_key_update(uint8_t* rx_payload)
{
  gzp_crypt_select_key(GZP_KEY_EXCHANGE);
  gzp_crypt(&rx_payload[1], &rx_payload[1], GZP_CMD_KEY_UPDATE_PAYLOAD_LENGTH - 1);
  if(gzp_validate_id(&rx_payload[GZP_CMD_KEY_UPDATE_VALIDATION_ID]))
  {
    gzp_crypt_set_dyn_key(&rx_payload[GZP_CMD_KEY_UPDATE_NEW_KEY]);
  }
}
Exemple #3
0
static void gzp_process_encrypted_user_data(uint8_t* rx_payload, uint8_t length)
{
  uint8_t tx_payload[GZP_CMD_ENCRYPTED_USER_DATA_RESP_PAYLOAD_LENGTH];

  if(gzp_id_req_received())
  {
    gzp_crypt_select_key(GZP_ID_EXCHANGE);
  }
  else
  {
    gzp_crypt_select_key(GZP_DATA_EXCHANGE);
  }

  gzp_crypt(&rx_payload[1], &rx_payload[1], length - 1);
  if(gzp_validate_id(&rx_payload[GZP_CMD_ENCRYPTED_USER_DATA_VALIDATION_ID]))
  {
    gzp_encrypted_user_data_length = length - GZP_ENCRYPTED_USER_DATA_PACKET_OVERHEAD;
    memcpy((void*)gzp_encrypted_user_data, &rx_payload[GZP_CMD_ENCRYPTED_USER_DATA_PAYLOAD], gzp_encrypted_user_data_length);
  }

  // Build response packet
  tx_payload[0] = (uint8_t)GZP_CMD_ENCRYPTED_USER_DATA_RESP;
  gzp_add_validation_id(&tx_payload[GZP_CMD_ENCRYPTED_USER_DATA_RESP_VALIDATION_ID]);
  gzp_crypt(&tx_payload[GZP_CMD_ENCRYPTED_USER_DATA_RESP_VALIDATION_ID], &tx_payload[GZP_CMD_ENCRYPTED_USER_DATA_RESP_VALIDATION_ID], GZP_VALIDATION_ID_LENGTH);
  gzp_get_session_counter(&tx_payload[GZP_CMD_ENCRYPTED_USER_DATA_RESP_SESSION_TOKEN]);

  // Update "session token" only if no ID request is pending
  if(!gzp_id_req_received())
  {
    gzp_crypt_set_session_token(&tx_payload[GZP_CMD_ENCRYPTED_USER_DATA_RESP_SESSION_TOKEN]);
  }

  ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR);
  gzp_preload_ack(tx_payload, GZP_CMD_ENCRYPTED_USER_DATA_RESP_PAYLOAD_LENGTH, GZP_DATA_PIPE);
  ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR);
}
Exemple #4
0
static void gzp_process_id_fetch(uint8_t* rx_payload)
{
  uint8_t tx_payload[GZP_CMD_HOST_ID_FETCH_RESP_PAYLOAD_LENGTH];

  if(gzp_id_req_received())
  {
    gzp_crypt_select_key(GZP_ID_EXCHANGE);
    gzp_crypt(&rx_payload[1], &rx_payload[1], GZP_CMD_HOST_ID_FETCH_PAYLOAD_LENGTH - 1);
    if(gzp_validate_id(&rx_payload[GZP_CMD_HOST_ID_FETCH_VALIDATION_ID]))
    {
      switch(gzp_id_req_stat)
      {
        case GZP_ID_REQ_PENDING_AND_GRANTED:
          tx_payload[GZP_CMD_HOST_ID_FETCH_RESP_STATUS] = (uint8_t)GZP_ID_RESP_GRANTED;
          gzp_get_host_id(&tx_payload[GZP_CMD_HOST_ID_FETCH_RESP_HOST_ID]);
          gzp_id_req_stat = GZP_ID_REQ_IDLE;
          break;
        case GZP_ID_REQ_PENDING_AND_REJECTED:
          tx_payload[GZP_CMD_HOST_ID_FETCH_RESP_STATUS] = (uint8_t)GZP_ID_RESP_REJECTED;
          gzp_id_req_stat = GZP_ID_REQ_IDLE;
          break;
        case GZP_ID_REQ_PENDING:
        default:
          tx_payload[GZP_CMD_HOST_ID_FETCH_RESP_STATUS] = (uint8_t)GZP_ID_RESP_PENDING;
          break;
      }

      tx_payload[0] = (uint8_t)GZP_CMD_HOST_ID_FETCH_RESP;
      gzp_add_validation_id(&tx_payload[GZP_CMD_HOST_ID_FETCH_RESP_VALIDATION_ID]);
      gzp_crypt(&tx_payload[1], &tx_payload[1], GZP_CMD_HOST_ID_FETCH_RESP_PAYLOAD_LENGTH - 1);
      
      ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR);
      gzp_preload_ack(tx_payload, GZP_CMD_HOST_ID_FETCH_RESP_PAYLOAD_LENGTH, GZP_DATA_PIPE);
      ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR);
    }
  }
}
Exemple #5
0
static bool gzp_crypt_tx_transaction(const uint8_t *src, uint8_t length)
{
    uint8_t tx_packet[GZP_MAX_FW_PAYLOAD_LENGTH];
    uint8_t rx_packet[GZP_MAX_ACK_PAYLOAD_LENGTH];
    uint8_t tx_packet_length;

    gzp_tx_rx_trans_result_t result;

    tx_packet_length = length + (uint8_t)GZP_ENCRYPTED_USER_DATA_PACKET_OVERHEAD;

    // Assemble tx packet
    tx_packet[0] = (uint8_t)GZP_CMD_ENCRYPTED_USER_DATA;
    gzp_add_validation_id(&tx_packet[GZP_CMD_ENCRYPTED_USER_DATA_VALIDATION_ID]);
    memcpy(&tx_packet[GZP_CMD_ENCRYPTED_USER_DATA_PAYLOAD], (uint8_t*)src, length);

    // Encrypt tx packet
    if(gzp_id_req_pending)
    {
        gzp_crypt_select_key(GZP_ID_EXCHANGE);
    }
    else
    {
        gzp_crypt_select_key(GZP_DATA_EXCHANGE);
    }
    gzp_crypt(&tx_packet[1], &tx_packet[1], tx_packet_length - 1);

    // If packet was successfully sent AND a response packet was received
    result = gzp_tx_rx_transaction(tx_packet, tx_packet_length, rx_packet, NULL, GZP_DATA_PIPE);
    if(result == GZP_TX_RX_SUCCESS)
    {
        if(rx_packet[0] == (uint8_t)GZP_CMD_ENCRYPTED_USER_DATA_RESP)
        {
            gzp_crypt(&rx_packet[GZP_CMD_ENCRYPTED_USER_DATA_RESP_VALIDATION_ID], &rx_packet[GZP_CMD_ENCRYPTED_USER_DATA_RESP_VALIDATION_ID], GZP_VALIDATION_ID_LENGTH);

            // Validate response in order to know whether packet was correctly decrypted by host
            if(gzp_validate_id(&rx_packet[GZP_CMD_ENCRYPTED_USER_DATA_RESP_VALIDATION_ID]))
            {
                // Update session token if normal operation (!gzp_id_req_pending)
                if(!gzp_id_req_pending)
                {
                    gzp_crypt_set_session_token(&rx_packet[GZP_CMD_ENCRYPTED_USER_DATA_RESP_SESSION_TOKEN]);
                }
                return true;
            }
            else
            {
                //print_string("GZP_CRYPT_TX_TRANS: Validation ID bad\r\n");
                return false;
            }
        }
        else
        {
            //print_string("GZP_CRYPT_TX_TRANS: Bad CMD. \r\n");
            return false;
        }
    }
    else
    {
        //print_string("GZP_CRYPT_TX_TRANS: gzp_tx_rx_trans not SUCCESS\r\n");
        return false;
    }
}
Exemple #6
0
gzp_id_req_res_t gzp_id_req_send()
{
    uint8_t tx_packet[GZP_CMD_HOST_ID_REQ_PAYLOAD_LENGTH];
    uint8_t rx_packet[GZP_MAX_ACK_PAYLOAD_LENGTH];
    gzp_tx_rx_trans_result_t trans_result;

    // If no ID request is pending, send new "ID request"
    if(!gzp_id_req_pending)
    {
        // Build "Host ID request packet"
        tx_packet[0] = (uint8_t)GZP_CMD_HOST_ID_REQ;

        // Generate new session token
        gzp_random_numbers_generate(&tx_packet[GZP_CMD_HOST_ID_REQ_SESSION_TOKEN], GZP_SESSION_TOKEN_LENGTH);

        // Send "Host ID request"
        if(gzp_tx_packet(tx_packet, GZP_CMD_HOST_ID_REQ_PAYLOAD_LENGTH, GZP_DATA_PIPE))
        {
            // Update session token if "Host ID request" was successfully transmitted
            gzp_crypt_set_session_token(&tx_packet[GZP_CMD_HOST_ID_REQ_SESSION_TOKEN]);
            gzp_id_req_pending = true;

            return GZP_ID_RESP_PENDING;
        }
    }
    else // If "ID request is pending" send "fetch ID" packet
    {
        // Build "host ID fetch" packet
        tx_packet[0] = (uint8_t)GZP_CMD_HOST_ID_FETCH;
        gzp_add_validation_id(&tx_packet[GZP_CMD_HOST_ID_FETCH_VALIDATION_ID]);

        // Encrypt "host ID fetch" packet
        gzp_crypt_select_key(GZP_ID_EXCHANGE);
        gzp_crypt(&tx_packet[1], &tx_packet[1], GZP_CMD_HOST_ID_FETCH_PAYLOAD_LENGTH - 1);

        trans_result = gzp_tx_rx_transaction(tx_packet, GZP_CMD_HOST_ID_FETCH_PAYLOAD_LENGTH, rx_packet, NULL, GZP_DATA_PIPE);
        // If packet was successfully sent AND a response packet was received
        if(trans_result == GZP_TX_RX_SUCCESS)
        {
            // Validate response packet
            if(rx_packet[0] == (uint8_t)GZP_CMD_HOST_ID_FETCH_RESP)
            {
                gzp_crypt(&rx_packet[1], &rx_packet[1], GZP_CMD_HOST_ID_FETCH_RESP_PAYLOAD_LENGTH - 1);
                if(gzp_validate_id(&rx_packet[GZP_CMD_HOST_ID_FETCH_RESP_VALIDATION_ID]))
                {
                    switch(rx_packet[GZP_CMD_HOST_ID_FETCH_RESP_STATUS])
                    {
                    case GZP_ID_RESP_PENDING:
                        break;
                    case GZP_ID_RESP_REJECTED:
                        gzp_id_req_pending = false;
                        break;
                    case GZP_ID_RESP_GRANTED:
                        gzp_set_host_id(&rx_packet[GZP_CMD_HOST_ID_FETCH_RESP_HOST_ID]);
                        gzp_random_numbers_generate(dyn_key, GZP_DYN_KEY_LENGTH);
                        gzp_crypt_set_dyn_key(dyn_key);
                        #ifndef GZP_NV_STORAGE_DISABLE
                        (void)gzp_params_store(true);
                        #endif
                        gzp_id_req_pending = false;
                        break;
                    default:
                        break;
                    }

                    return (gzp_id_req_res_t)rx_packet[GZP_CMD_HOST_ID_FETCH_RESP_STATUS];
                }
                else
                {
                    gzp_id_req_pending = false;
                    return GZP_ID_RESP_REJECTED;
                }
            }
        }
    }

    gzp_id_req_pending = false;
    return GZP_ID_RESP_FAILED;
}