43#define STATIC_USB_BACKEND "usb" 
   44#define STATIC_HTTP_BACKEND "http" 
   49               "Host challenge length mismatch");
 
   52               "Message buffer size mismatch");
 
   55#define LIST_SEPARATORS ":,;|" 
   69  DBG_CRYPTO(data, data_len, 
"Compute MAC (%3d Bytes): ", data_len);
 
   78  if (connector == NULL || connector->
bf == NULL) {
 
   83  yrc = connector->
bf->backend_send_msg(connector->
connection, msg, response);
 
   98  msg_len = msg->
st.len;
 
  105  msg->
st.len = htons(msg->
st.len);
 
  107  msg->
st.len = ntohs(msg->
st.len);
 
  110                   session->s.mac_chaining_value);
 
  114  return send_msg(
session->parent, msg, response);
 
  121    while (!++ctr[i--] && i > 0)
 
  127                        const uint8_t *data, 
size_t data_len,
 
  129                        size_t *response_len) {
 
  136  if (connector == NULL || (data_len != 0 && data == NULL) ||
 
  137      response_cmd == NULL || response == NULL || response_len == NULL) {
 
  142  if (data_len > 
sizeof(msg.
st.data)) {
 
  143    DBG_ERR(
"Tried to transfer oversized data (%zu > %zu)", data_len,
 
  144            sizeof(msg.
st.data));
 
  149  msg.
st.len = data_len;
 
  151    memcpy(msg.
st.data, data, data_len);
 
  154  DBG_DUMPINFO(msg.
raw, data_len + 3, 
"Sending cmd %02x (%3zu Bytes): ", cmd,
 
  157  yrc = send_msg(connector, &msg, &response_msg);
 
  163  if (*response_len < response_msg.
st.len) {
 
  165                "%s (received %3d Bytes, can fit %3zu Bytes) ",
 
  171  *response_cmd = response_msg.
st.cmd;
 
  173  memcpy(response, response_msg.
st.data, response_msg.
st.len);
 
  174  *response_len = response_msg.
st.len;
 
 
  183    _DEVICE_INVALID_COMMAND = 0x01, 
 
  184    _DEVICE_INVALID_DATA = 0x02,    
 
  185    _DEVICE_INVALID_SESSION = 0x03, 
 
  186    _DEVICE_AUTHENTICATION_FAILED =
 
  188    _DEVICE_SESSIONS_FULL = 0x05,  
 
  189    _DEVICE_SESSION_FAILED = 0x06, 
 
  190    _DEVICE_STORAGE_FAILED = 0x07, 
 
  191    _DEVICE_WRONG_LENGTH = 0x08,   
 
  192    _DEVICE_INSUFFICIENT_PERMISSIONS = 0x09, 
 
  193    _DEVICE_LOG_FULL = 0x0a, 
 
  194    _DEVICE_OBJECT_NOT_FOUND = 0x0b,             
 
  195    _DEVICE_INVALID_ID = 0x0c,                   
 
  196    _DEVICE_SSH_CA_CONSTRAINT_VIOLIATION = 0x0e, 
 
  197    _DEVICE_INVALID_OTP = 0x0f,                  
 
  198    _DEVICE_DEMO_MODE = 0x10,     
 
  199    _DEVICE_OBJECT_EXISTS = 0x11, 
 
  200    _DEVICE_COMMAND_UNEXECUTED =
 
  208    case _DEVICE_INVALID_COMMAND:
 
  211    case _DEVICE_INVALID_DATA:
 
  214    case _DEVICE_INVALID_SESSION:
 
  217    case _DEVICE_AUTHENTICATION_FAILED:
 
  220    case _DEVICE_SESSIONS_FULL:
 
  223    case _DEVICE_SESSION_FAILED:
 
  226    case _DEVICE_STORAGE_FAILED:
 
  229    case _DEVICE_WRONG_LENGTH:
 
  232    case _DEVICE_INSUFFICIENT_PERMISSIONS:
 
  235    case _DEVICE_LOG_FULL:
 
  238    case _DEVICE_OBJECT_NOT_FOUND:
 
  241    case _DEVICE_INVALID_ID:
 
  244    case _DEVICE_SSH_CA_CONSTRAINT_VIOLIATION:
 
  247    case _DEVICE_INVALID_OTP:
 
  250    case _DEVICE_DEMO_MODE:
 
  253    case _DEVICE_OBJECT_EXISTS:
 
  256    case _DEVICE_COMMAND_UNEXECUTED:
 
  264                              const uint8_t *data, 
size_t data_len,
 
  266                              size_t *response_len) {
 
  284  if (
session == NULL || (data_len != 0 && data == NULL) ||
 
  285      response_cmd == NULL || response == NULL || response_len == NULL) {
 
  296  decrypted_data[0] = cmd;
 
  297  decrypted_data[1] = (data_len & 0xff00) >> 8;
 
  298  decrypted_data[2] = data_len & 0x00ff;
 
  299  memcpy(decrypted_data + 3, data, data_len);
 
  300  work_buf_len = 3 + data_len;
 
  303               "Sending cmd %02x (%3lu Bytes): ", cmd,
 
  304               (
unsigned long) data_len + 3);
 
  313             "CBC encrypting (%3d Bytes): ", work_buf_len);
 
  316  aes_cbc_encrypt(decrypted_data, work_buf + 1, work_buf_len, encrypted_ctr,
 
  322             "Ciphertext (%3d Bytes): ", work_buf_len);
 
  324  msg.
st.cmd = YHC_SESSION_MESSAGE;
 
  325  msg.
st.len = 1 + work_buf_len;
 
  327  memcpy(msg.
st.data, work_buf, work_buf_len + 1);
 
  329  yrc = send_authenticated_msg(
session, &msg, &response_msg);
 
  336    yh_rc translated = translate_device_error(response_msg.
st.data[0]);
 
  340    response[0] = response_msg.
st.data[0];
 
  351  response_msg.
st.len = htons(response_msg.
st.len);
 
  355  response_msg.
st.len = ntohs(response_msg.
st.len);
 
  357  if (memcmp(response_msg.
st.data + response_msg.
st.len - 
SCP_MAC_LEN, mac_buf,
 
  365  DBG_INFO(
"Response MAC successfully verified");
 
  369  if (
session->s.sid != response_msg.
st.data[0]) {
 
  370    DBG_ERR(
"Session ID mismatch, expected %d, got %d", 
session->s.sid,
 
  371            response_msg.
st.data[0]);
 
  384             "CBC decrypting (%3d Bytes): ", 
out_len);
 
  388                  encrypted_ctr, &aes_ctx);
 
  404  *response_cmd = decrypted_data[0];
 
  405  memcpy(response, decrypted_data + 3, *response_len);
 
  417                         size_t data_len, 
yh_cmd *response_cmd,
 
  418                         uint8_t *response, 
size_t *response_len) {
 
  420  size_t saved_len = *response_len;
 
  422  yh_rc yrc = _send_secure_msg(
session, cmd, data, data_len, response_cmd,
 
  423                               response, response_len);
 
  438    *response_len = saved_len;
 
  439    yrc = _send_secure_msg(
session, cmd, data, data_len, response_cmd, response,
 
 
  457  if (L == 0x40 || L == 0x80)
 
  459  else if (L == 0xc0 || L == 0x100)
 
  473  *ptr++ = (L & 0xff00) >> 8;
 
  474  *ptr++ = (L & 0x00ff);
 
  486  for (i = 0; i < n_iterations; i++) {
 
  493  memcpy(key_out, result, L / 8);
 
  557  return memcmp(card_cryptogram, calculated_card_cryptogram,
 
  574static yh_rc derive_keys(
const uint8_t *password, 
size_t password_len,
 
  594                                const uint8_t *password, 
size_t password_len,
 
  597  if (connector == NULL || password == NULL || 
session == NULL) {
 
  605  yh_rc yrc = derive_keys(password, password_len, key_enc, key_mac);
 
 
  617                        const uint8_t *key_enc, 
size_t key_enc_len,
 
  618                        const uint8_t *key_mac, 
size_t key_mac_len,
 
  629  if (connector == NULL || key_enc == NULL || key_enc_len != 
SCP_KEY_LEN ||
 
  635  if (!
rand_generate(host_challenge, 
sizeof(host_challenge))) {
 
  641    if (new_session == NULL) {
 
  658  msg.
st.cmd = YHC_CREATE_SESSION;
 
  661  uint16_t authkey_id_n = htons(authkey_id);
 
  668  yrc = send_msg(connector, &msg, &response_msg);
 
  674  if (response_msg.
st.cmd != YHC_CREATE_SESSION_R) {
 
  675    yh_rc translated = translate_device_error(response_msg.
st.data[0]);
 
  677            response_msg.
st.data[0]);
 
  687  ptr = response_msg.
st.data;
 
  690  new_session->
s.
sid = (*ptr++);
 
  699  DBG_INFO(
"Received Session ID: %d", new_session->
s.
sid);
 
  707    derive_s_enc(&new_session->
s, key_enc, key_enc_len, new_session->
context);
 
  712    derive_s_mac(&new_session->
s, key_mac, key_mac_len, new_session->
context);
 
  717    derive_s_rmac(&new_session->
s, key_mac, key_enc_len, new_session->
context);
 
  725  yrc = verify_card_cryptogram(&new_session->
s, new_session->
context,
 
  732  DBG_INFO(
"Card cryptogram successfully verified");
 
  735  new_session->
parent = connector;
 
  744  (new_session) = NULL;
 
 
  753                                  size_t card_cryptogram_len,
 
  763  if (connector == NULL || 
context == NULL || card_cryptogram == NULL ||
 
  769  if (!
rand_generate(host_challenge, 
sizeof(host_challenge))) {
 
  777  if (new_session == NULL) {
 
  783  msg.
st.cmd = YHC_CREATE_SESSION;
 
  786  uint16_t authkey_id_n = htons(authkey_id);
 
  793  yrc = send_msg(connector, &msg, &response_msg);
 
  799  if (response_msg.
st.cmd != YHC_CREATE_SESSION_R) {
 
  800    yh_rc translated = translate_device_error(response_msg.
st.data[0]);
 
  802            response_msg.
st.data[0]);
 
  812  ptr = response_msg.
st.data;
 
  815  new_session->
s.
sid = (*ptr++);
 
  824  DBG_INFO(
"Received Session ID: %d", new_session->
s.
sid);
 
  831  new_session->
parent = connector;
 
  840  (new_session) = NULL;
 
 
  849  size_t key_senc_len, 
const uint8_t *key_smac, 
size_t key_smac_len,
 
  850  const uint8_t *key_srmac, 
size_t key_srmac_len, 
uint8_t *card_cryptogram,
 
  851  size_t card_cryptogram_len) { 
 
  853  if (connector == NULL || 
session == NULL || key_senc == NULL ||
 
  854      key_senc_len != 
YH_KEY_LEN || key_smac == NULL ||
 
  855      key_smac_len != 
YH_KEY_LEN || key_srmac == NULL ||
 
  856      key_srmac_len != 
YH_KEY_LEN || card_cryptogram == NULL ||
 
  885  DBG_INFO(
"Card cryptogram successfully verified");
 
 
  914  if (connector == NULL || 
major == NULL || 
minor == NULL || 
patch == NULL) {
 
 
  928  if (connector == NULL || address == NULL) {
 
  933  *address = (
char *) connector->
address;
 
 
  943  if (connector == NULL) {
 
  964  size_t response_len = 
sizeof(response);
 
  968                          &response_cmd, response.buf, &response_len);
 
  975    yh_rc translated = translate_device_error(response.buf[0]);
 
  982    *
major = response.major;
 
  986    *
minor = response.minor;
 
  990    *
patch = response.patch;
 
  994    *
serial = ntohl(response.serial);
 
  997  if (log_total != NULL) {
 
  998    *log_total = response.log_total;
 
 1001  if (log_used != NULL) {
 
 1002    *log_used = response.log_used;
 
 1005  if (algorithms != NULL && n_algorithms) {
 
 1006    size_t items = response_len - 
sizeof(response.major) -
 
 1007                   sizeof(response.minor) - 
sizeof(response.patch) -
 
 1008                   sizeof(response.serial) - 
sizeof(response.log_total) -
 
 1009                   sizeof(response.log_used);
 
 1010    if (*n_algorithms < items) {
 
 1011      DBG_ERR(
"Algorithms buffer too small");
 
 1014    for (
size_t i = 0; i < items; i++) {
 
 1015      algorithms[i] = response.algorithms[i];
 
 1017    *n_algorithms = items;
 
 
 1025#define LIST_DOMAINS 3 
 1026#define LIST_CAPABILITIES 4 
 1027#define LIST_ALGORITHM 5 
 1046  size_t response_len = 
sizeof(response);
 
 1053    *dataptr++ = 
id >> 8 & 0xff;
 
 1054    *dataptr++ = 
id & 0xff;
 
 1064    *dataptr++ = 
domains >> 8 & 0xff;
 
 1080  bool send_capabilities = 
false;
 
 1083      send_capabilities = 
true;
 
 1088  if (send_capabilities == 
true) {
 
 1096                           &response_cmd, response, &response_len);
 
 1103    yh_rc translated = translate_device_error(response[0]);
 
 1110    DBG_ERR(
"Objects buffer too small");
 
 1115  for (
uint16_t i = 0; i < response_len; i += 4) {
 
 1118    objects[i / 4].
id = ntohs(*((
uint16_t *) (response + i)));
 
 1119    objects[i / 4].
type = response[i + 2];
 
 1120    objects[i / 4].
sequence = response[i + 3];
 
 
 1140#pragma pack(push, 1) 
 1156  size_t response_len = 
sizeof(response);
 
 1162  *dataptr++ = 
id >> 8 & 0xff;
 
 1163  *dataptr++ = 
id & 0xff;
 
 1168                           &response_cmd, response.buf, &response_len);
 
 1175    yh_rc translated = translate_device_error(response.buf[0]);
 
 1181  if (response_len == 
sizeof(response)) {
 
 1186      object->id = htons(response.id);
 
 1188      object->len = htons(response.len);
 
 1190      object->domains = htons(response.domains);
 
 1192      object->type = response.type;
 
 1194      object->algorithm = response.algorithm;
 
 1196      object->sequence = response.sequence;
 
 1198      object->origin = response.origin;
 
 1207    DBG_ERR(
"Wrong response length, expecting %lu or 0, received %lu",
 
 1209            (
unsigned long) response_len);
 
 
 1219  if (
session == NULL || data == NULL || data_len == NULL) {
 
 1224  uint8_t cmd[2] = {
id >> 8, 
id & 0xff};
 
 1227  size_t response_len = 
sizeof(response);
 
 1230                                 &response_cmd, response, &response_len);
 
 1238    yh_rc translated = translate_device_error(response[0]);
 
 1244  if (response_len > *data_len) {
 
 1251  *data_len = response_len - 1;
 
 1252  memcpy(data, response + 1, *data_len);
 
 
 1267  size_t response_len = 
sizeof(response);
 
 1271                           response, &response_len);
 
 1278    yh_rc translated = translate_device_error(response[0]);
 
 
 1291  if (
session == NULL || in == NULL || out == NULL || 
out_len == NULL) {
 
 1305        DBG_ERR(
"Data length must be 20, 32, 48 or 64");
 
 1311#pragma pack(push, 1) 
 1324  data.key_id = htons(
key_id);
 
 1337    yh_rc translated = translate_device_error(out[0]);
 
 
 1350  if (
session == NULL || in == NULL || out == NULL || 
out_len == NULL) {
 
 1363      DBG_ERR(
"Data length must be 20, 32, 48 or 64");
 
 1369#pragma pack(push, 1) 
 1384  data.key_id = htons(
key_id);
 
 1386  data.mgf1Algo = mgf1Algo;
 
 1390  data.salt_len = htons(salt_len);
 
 1402    yh_rc translated = translate_device_error(out[0]);
 
 
 1415  if (
session == NULL || in == NULL || out == NULL || 
out_len == NULL) {
 
 1430      DBG_ERR(
"Data length must be 20, 28, 32, 48, 64 or 66");
 
 1436#pragma pack(push, 1) 
 1449  data.key_id = htons(
key_id);
 
 1461    yh_rc translated = translate_device_error(out[0]);
 
 
 1474  if (
session == NULL || in == NULL || out == NULL || 
out_len == NULL) {
 
 1486#pragma pack(push, 1) 
 1499  data.key_id = htons(
key_id);
 
 1511    yh_rc translated = translate_device_error(out[0]);
 
 
 1523  if (
session == NULL || in == NULL || out == NULL || 
out_len == NULL) {
 
 1538  data[0] = htons(
key_id) & 0xff;
 
 1539  data[1] = htons(
key_id) >> 8;
 
 1552    yh_rc translated = translate_device_error(out[0]);
 
 
 1574  data.len = htons(
len);
 
 1577                           sizeof(data), &response_cmd, out, 
out_len);
 
 1584    yh_rc translated = translate_device_error(out[0]);
 
 
 1597#pragma pack(push, 1) 
 1616  size_t response_len = 
sizeof(response);
 
 1619  k.key_id = htons(*
key_id);
 
 1632  uint16_t len = 
sizeof(k.key_id) + 
sizeof(k.domains) + 
sizeof(k.capabilities) +
 
 1633                 sizeof(k.algo) + 
sizeof(k.label) + 
key_len;
 
 1635                                 &response_cmd, response.buf, &response_len);
 
 1643    yh_rc translated = translate_device_error(response.buf[0]);
 
 1649  *
key_id = ntohs(response.key_id);
 
 1671    component_len = 128;
 
 1673    component_len = 192;
 
 1675    component_len = 256;
 
 1679  memcpy(keybuf, 
p, component_len);
 
 1680  memcpy(keybuf + component_len, q, component_len);
 
 
 1762#pragma pack(push, 1) 
 1782  size_t response_len = 
sizeof(response);
 
 1784  size_t max_len = 64;
 
 1785  int len = 
sizeof(k) - 
sizeof(k.key);
 
 1787  k.key_id = htons(*
key_id);
 
 1803    DBG_ERR(
"Too long key supplied, max %lu bytes allowed",
 
 1804            (
unsigned long) max_len);
 
 1812                           response.buf, &response_len);
 
 1820    yh_rc translated = translate_device_error(response.buf[0]);
 
 1826  *
key_id = ntohs(response.key_id);
 
 
 1845#pragma pack(push, 1) 
 1856  int data_len = 
sizeof(data);
 
 1864  size_t response_len = 
sizeof(response);
 
 1867  data.key_id = htons(*
key_id);
 
 1872  data.domains = htons(
domains);
 
 1880                       &response_cmd, response.buf, &response_len);
 
 1882    DBG_ERR(
"Failed to send GENERATE ASYMMETRIC KEY command: %s",
 
 1888    yh_rc translated = translate_device_error(response.buf[0]);
 
 1894  *
key_id = ntohs(response.key_id);
 
 1940                          const uint8_t *signature, 
size_t signature_len,
 
 1941                          const uint8_t *data, 
size_t data_len,
 
 1944  if (
session == NULL || signature == NULL || data == NULL ||
 
 1961  size_t response_len = 
sizeof(response);
 
 1968  memcpy(cmd_data + cmd_data_len, signature, signature_len);
 
 1969  cmd_data_len += signature_len;
 
 1970  memcpy(cmd_data + cmd_data_len, data, data_len);
 
 1971  cmd_data_len += data_len;
 
 1974                           &response_cmd, response, &response_len);
 
 1981    yh_rc translated = translate_device_error(response[0]);
 
 1987  *verified = response[0];
 
 
 2005#pragma pack(push, 1) 
 2024  size_t response_len = 
sizeof(response);
 
 2027  data.key_id = htons(*
key_id);
 
 2032  data.domains = htons(
domains);
 
 2040                       &response_cmd, response.buf, &response_len);
 
 2047    yh_rc translated = translate_device_error(response.buf[0]);
 
 2053  *
key_id = ntohs(response.key_id);
 
 
 2063  if (
session == NULL || in == NULL || out == NULL || 
out_len == NULL) {
 
 2073#pragma pack(push, 1) 
 2086  data.key_id = htons(
key_id);
 
 2098    yh_rc translated = translate_device_error(out[0]);
 
 
 2112  if (
session == NULL || in == NULL || out == NULL || 
out_len == NULL ||
 
 2118#pragma pack(push, 1) 
 2133  data.key_id = htons(
key_id);
 
 2134  len += 
sizeof(data.key_id);
 
 2136  data.mgf1Algo = mgf1Algo;
 
 2137  len += 
sizeof(data.mgf1Algo);
 
 2141    DBG_ERR(
"Wrong input length");
 
 2148    DBG_ERR(
"Wrong label length");
 
 2165    yh_rc translated = translate_device_error(out[0]);
 
 
 2178  if (
session == NULL || in == NULL || out == NULL || 
out_len == NULL) {
 
 2188#pragma pack(push, 1) 
 2201  data.key_id = htons(
key_id);
 
 2213    yh_rc translated = translate_device_error(out[0]);
 
 
 2230#pragma pack(push, 1) 
 2243  size_t response_len = 
sizeof(response);
 
 2246  data.id = htons(
id);
 
 2249                           &response_cmd, response, &response_len);
 
 2256    yh_rc translated = translate_device_error(response[0]);
 
 
 2274#pragma pack(push, 1) 
 2288  data.key_id = htons(wrapping_key_id);
 
 2300    yh_rc translated = translate_device_error(out[0]);
 
 
 2324#pragma pack(push, 1) 
 2336  size_t response_len = 
sizeof(response);
 
 2340  data.key_id = htons(wrapping_key_id);
 
 2344                           &response_cmd, response, &response_len);
 
 2351    yh_rc translated = translate_device_error(response[0]);
 
 
 2377#pragma pack(push, 1) 
 2399  size_t response_len = 
sizeof(response);
 
 2427  data.key_id = htons(*
key_id);
 
 2430  data.domains = htons(
domains);
 
 2438                           &response_cmd, response.buf, &response_len);
 
 2446    yh_rc translated = translate_device_error(response.buf[0]);
 
 2452  *
key_id = ntohs(response.key_id);
 
 
 2473#pragma pack(push, 1) 
 2494  size_t response_len = 
sizeof(response);
 
 2497  data.key_id = htons(*
key_id);
 
 2502  data.domains = htons(
domains);
 
 2512                           &response_cmd, response.buf, &response_len);
 
 2519    yh_rc translated = translate_device_error(response.buf[0]);
 
 2525  *
key_id = ntohs(response.key_id);
 
 
 2535  if (
session == NULL || out == NULL || n_items == NULL) {
 
 2551  size_t response_len = 
sizeof(response);
 
 2555                           response.buf, &response_len);
 
 2562    yh_rc translated = translate_device_error(response.buf[0]);
 
 2568  if (unlogged_boot) {
 
 2569    *unlogged_boot = ntohs(response.log_overflow_boot);
 
 2572  if (unlogged_auth) {
 
 2573    *unlogged_auth = ntohs(response.log_overflow_auth);
 
 2578      "Response contain more items than the maximum number of log entries");
 
 2582  if (response.items > *n_items) {
 
 2583    DBG_ERR(
"Log buffer too small, needed at lest %d, got %zu", response.items,
 
 2588  *n_items = response.items;
 
 2591  for (
uint16_t i = 0; i < *n_items; i++) {
 
 2592    out[i].number = ntohs(ptr[i].number);
 
 2593    out[i].command = ptr[i].
command;
 
 2594    out[i].length = ntohs(ptr[i].length);
 
 2595    out[i].session_key = ntohs(ptr[i].session_key);
 
 2596    out[i].target_key = ntohs(ptr[i].target_key);
 
 2597    out[i].second_key = ntohs(ptr[i].second_key);
 
 2598    out[i].result = ptr[i].
result;
 
 2599    out[i].systick = ntohl(ptr[i].systick);
 
 
 2615  size_t response_len = 
sizeof(response);
 
 2618  memcpy(data, &index_h, 
sizeof(index_h));
 
 2620                           &response_cmd, response, &response_len);
 
 2627    yh_rc translated = translate_device_error(response[0]);
 
 
 2648  uint16_t object_id_h = htons(object_id);
 
 2649  memcpy(data, &object_id_h, 
sizeof(object_id_h));
 
 2658    yh_rc translated = translate_device_error(out[0]);
 
 
 2672  if (
session == NULL || object_id == NULL || 
label == NULL ||
 
 2680#pragma pack(push, 1) 
 2701  size_t response_len = 
sizeof(response);
 
 2704  data.object_id = htons(*object_id);
 
 2709  data.domains = htons(
domains);
 
 2715  if (
in_len > 
sizeof(data.bytes)) {
 
 2716    DBG_ERR(
"Data length must be in [0, %lu]\n",
 
 2717            (
unsigned long) 
sizeof(data.bytes));
 
 2721  data_len = 
in_len + 
sizeof(data) - 
sizeof(data.bytes);
 
 2725                           &response_cmd, response.buf, &response_len);
 
 2733    yh_rc translated = translate_device_error(response.buf[0]);
 
 2739  *object_id = ntohs(response.object_id);
 
 2740  DBG_INFO(
"Stored Opaque Object 0x%04x", *object_id);
 
 
 2749  if (
session == NULL || in == NULL || out == NULL || 
out_len == NULL ||
 
 2757#pragma pack(push, 1) 
 2772  data.key_id = htons(
key_id);
 
 2774  data.template_id = htons(template_id);
 
 2776  data.algo = sig_algo;
 
 2778  if (
in_len > 
sizeof(data.bytes)) {
 
 2779    DBG_ERR(
"Data length must be in [0, %lu]\n",
 
 2780            (
unsigned long) 
sizeof(data.bytes));
 
 2788                           data_len, &response_cmd, out, 
out_len);
 
 2790    DBG_ERR(
"Failed to send SIGN SSH CERTIFICATE command: %s",
 
 2796    yh_rc translated = translate_device_error(out[0]);
 
 
 2807  if (
session == NULL || out == NULL) {
 
 2816  uint16_t object_id_h = htons(object_id);
 
 2817  memcpy(data, &object_id_h, 
sizeof(object_id_h));
 
 2826    yh_rc translated = translate_device_error(out[0]);
 
 
 2841  if (
session == NULL || object_id == NULL || 
label == NULL ||
 
 2849#pragma pack(push, 1) 
 2871  size_t response_len = 
sizeof(response);
 
 2874  data.object_id = htons(*object_id);
 
 2879  data.domains = htons(
domains);
 
 2885  if (
in_len > 
sizeof(data.bytes)) {
 
 2886    DBG_ERR(
"Data length must be in [0, %lu]\n",
 
 2887            (
unsigned long) 
sizeof(data.bytes));
 
 2891  data_len = 
in_len + 
sizeof(data.object_id) + 
sizeof(data.domains) +
 
 2896                           &response_cmd, response.buf, &response_len);
 
 2903    yh_rc translated = translate_device_error(response.buf[0]);
 
 2909  *object_id = ntohs(response.object_id);
 
 2910  DBG_INFO(
"Stored Opaque Object 0x%04x", *object_id);
 
 
 2917  if (
session == NULL || sid == NULL) {
 
 
 2942  msg.
st.cmd = YHC_AUTHENTICATE_SESSION;
 
 2948  yrc = compute_host_cryptogram(
session, msg.
st.data + 1);
 
 2958  msg.
st.len = htons(msg.
st.len);
 
 2960  msg.
st.len = ntohs(msg.
st.len);
 
 2963                   session->s.mac_chaining_value);
 
 2971  yrc = send_msg(
session->parent, &msg, &response_msg);
 
 2977  if (response_msg.
st.cmd != YHC_AUTHENTICATE_SESSION_R) {
 
 
 2989  size_t key_enc_len, 
const uint8_t *key_mac, 
size_t key_mac_len) {
 
 2994      key_enc_len != 
YH_KEY_LEN || key_mac == NULL ||
 
 3000#pragma pack(push, 1) 
 3021  size_t response_len = 
sizeof(response);
 
 3027  data.key_id = htons(*
key_id);
 
 3032  data.domains = htons(
domains);
 
 3042                                 sizeof(data), &response_cmd, response.buf,
 
 3046    DBG_ERR(
"Failed to send PUT AUTHENTICATION KEY command: %s\n",
 
 3052    yh_rc translated = translate_device_error(response.buf[0]);
 
 3053    DBG_ERR(
"Unable to store authentication key: %s (%x)\n",
 
 3058  *
key_id = ntohs(response.key_id);
 
 
 3068  size_t password_len) {
 
 3080  yh_rc yrc = derive_keys(password, password_len, key_enc, key_mac);
 
 3086                                        key_enc, 
sizeof(key_enc), key_mac,
 
 
 3098                                        size_t key_mac_len) {
 
 3101      key_enc_len != 
YH_KEY_LEN || key_mac == NULL ||
 
 3107#pragma pack(push, 1) 
 3124  size_t response_len = 
sizeof(response);
 
 3127  data.key_id = htons(*
key_id);
 
 3129  memcpy(data.key_enc, key_enc, key_enc_len);
 
 3130  memcpy(data.key_mac, key_mac, key_mac_len);
 
 3133                                 data.buf, 
sizeof(data), &response_cmd,
 
 3134                                 response.buf, &response_len);
 
 3137    DBG_ERR(
"Failed to send CHANGE AUTHENTICATION KEY command: %s\n",
 
 3143    yh_rc translated = translate_device_error(response.buf[0]);
 
 3144    DBG_ERR(
"Unable to change authentication key: %s (%x)\n",
 
 3149  *
key_id = ntohs(response.key_id);
 
 
 3158                                                size_t password_len) {
 
 3159  if (
session == NULL || 
key_id == NULL || password == NULL) {
 
 3167  yh_rc yrc = derive_keys(password, password_len, key_enc, key_mac);
 
 3171                                            sizeof(key_enc), key_mac,
 
 
 3183  if (
session == NULL || key == NULL || private_id == NULL || out == NULL ||
 
 3188#pragma pack(push, 1) 
 3201  data.key_id = htons(
key_id);
 
 3202  memcpy(data.key, key, 
sizeof(data.key));
 
 3203  memcpy(data.private_id, private_id, 
sizeof(data.private_id));
 
 3206                                 sizeof(data), &response_cmd, out, 
out_len);
 
 3214    yh_rc translated = translate_device_error(out[0]);
 
 
 3230#pragma pack(push, 1) 
 3241  data.key_id = htons(
key_id);
 
 3244                                 sizeof(data), &response_cmd, out, 
out_len);
 
 3246    DBG_ERR(
"Failed to send RANDOMIZE OTP AEAD command: %s\n",
 
 3252    yh_rc translated = translate_device_error(out[0]);
 
 
 3262                          const uint8_t *aead, 
size_t aead_len,
 
 3267#pragma pack(push, 1) 
 3287  if (
session == NULL || aead == NULL || 
otp == NULL ||
 
 3288      aead_len != 
sizeof(data.aead)) {
 
 3294  size_t response_len = 
sizeof(response);
 
 3296  data.key_id = htons(
key_id);
 
 3297  memcpy(data.aead, aead, 
sizeof(data.aead));
 
 3298  memcpy(data.otp, 
otp, 
sizeof(data.otp));
 
 3302                       &response_cmd, response.buf, &response_len);
 
 3310    yh_rc translated = translate_device_error(response.buf[0]);
 
 3316  if (response_len != 
sizeof(response)) {
 
 3317    DBG_ERR(
"Wrong size returned");
 
 3322    *useCtr = response.useCtr;
 
 3325    *sessionCtr = response.sessionCtr;
 
 3328    *tstph = response.tstph;
 
 3331    *tstpl = response.tstpl;
 
 
 3348#pragma pack(push, 1) 
 3370  size_t response_len = 
sizeof(response);
 
 3378  } 
else if (
in_len == 24) {
 
 3381  } 
else if (
in_len == 32) {
 
 3384    DBG_ERR(
"Key length has to be 16, 24 or 32 bytes.");
 
 3388  data.key_id = htons(*
key_id);
 
 3393  data.domains = htons(
domains);
 
 3397  data.nonce_id = nonce_id;
 
 3402                           &response_cmd, response.buf, &response_len);
 
 3410    yh_rc translated = translate_device_error(response.buf[0]);
 
 3416  *
key_id = ntohs(response.key_id);
 
 
 3435#pragma pack(push, 1) 
 3456  size_t response_len = 
sizeof(response);
 
 3459  data.key_id = htons(*
key_id);
 
 3464  data.domains = htons(
domains);
 
 3470  data.nonce_id = nonce_id;
 
 3474                       &response_cmd, response.buf, &response_len);
 
 3477    DBG_ERR(
"Failed to send GENERATE OTP AEAD KEY command: %s",
 
 3483    yh_rc translated = translate_device_error(response.buf[0]);
 
 3489  *
key_id = ntohs(response.key_id);
 
 
 3503#pragma pack(push, 1) 
 3515  data.key_id = htons(
key_id);
 
 3516  data.attest_id = htons(attest_id);
 
 3520                       sizeof(data), &response_cmd, out, 
out_len);
 
 3522    DBG_ERR(
"Failed to send SIGN ATTESTATION CERTIFICATE command: %s\n",
 
 3528    yh_rc translated = translate_device_error(out[0]);
 
 
 3540  if (
session == NULL || val == NULL) {
 
 3550#pragma pack(push, 1) 
 3561  size_t outlen = 
sizeof(out);
 
 3565  data.len = htons(
len);
 
 3569                                 &response_cmd, out, &outlen);
 
 3576    yh_rc translated = translate_device_error(out[0]);
 
 
 3602    yh_rc translated = translate_device_error(out[0]);
 
 
 3620#pragma pack(push, 1) 
 3632  size_t response_len = 
sizeof(response);
 
 3635                                 &response_cmd, response.buf, &response_len);
 
 3642    yh_rc translated = translate_device_error(response.buf[0]);
 
 3648  if (total_records) {
 
 3649    *total_records = ntohs(response.total_records);
 
 3652    *free_records = ntohs(response.free_records);
 
 3655    *total_pages = ntohs(response.total_pages);
 
 3658    *free_pages = ntohs(response.free_pages);
 
 3661    *page_size = ntohs(response.page_size);
 
 
 3670  if (
session == NULL || in == NULL || out == NULL || 
out_len == NULL) {
 
 3682#pragma pack(push, 1) 
 3695  data.key_id = htons(
key_id);
 
 3707    yh_rc translated = translate_device_error(out[0]);
 
 
 3720  if (
session == NULL || in == NULL || out == NULL || 
out_len == NULL) {
 
 3732#pragma pack(push, 1) 
 3745  data.key_id = htons(
key_id);
 
 3757    yh_rc translated = translate_device_error(out[0]);
 
 
 3776  size_t response_len = 
sizeof(response);
 
 3780                           &response_cmd, response, &response_len);
 
 3787    yh_rc translated = translate_device_error(response[0]);
 
 
 3807  size_t response_len = 
sizeof(response);
 
 3810                           response, &response_len);
 
 3817    yh_rc translated = translate_device_error(response[0]);
 
 
 3829  if (connector != NULL && connector->
bf != NULL) {
 
 
 3839  if (verbosity == NULL) {
 
 
 3851  if (connector != NULL && connector->
bf != NULL) {
 
 
 3865static yh_rc load_backend(
const char *
name,
 
 3869    DBG_ERR(
"No name given to load_backend");
 
 3873    *bf = usb_backend_functions();
 
 3876    *bf = http_backend_functions();
 
 3879    DBG_ERR(
"Failed finding backend named '%s'", 
name);
 
 3886static yh_rc load_backend(
const char *
name, 
void **backend,
 
 3890  *backend = LoadLibrary(
name);
 
 3891  if (*backend == NULL) {
 
 3896    (void (*)(void)) GetProcAddress(*backend, 
"backend_functions"));
 
 3898  *backend = dlopen(
name, RTLD_NOW);
 
 3899  if (*backend == NULL) {
 
 3900    DBG_ERR(
"Failed loading '%s' with error: '%s'", 
name, dlerror());
 
 3912#define STATUS_ENDPOINT "/connector/status" 
 3913#define API_ENDPOINT "/connector/api" 
 3920  if (connector == NULL) {
 
 3925  if (*connector == NULL) {
 
 3930    (*connector)->status_url = strdup(
url);
 
 3931    if ((*connector)->status_url == NULL) {
 
 3935    (*connector)->api_url = strdup(
url);
 
 3936    if ((*connector)->api_url == NULL) {
 
 3941    (*connector)->status_url =
 
 3943    if ((*connector)->status_url == NULL) {
 
 3949    (*connector)->api_url = calloc(1, strlen(
url) + strlen(
API_ENDPOINT) + 1);
 
 3950    if ((*connector)->api_url == NULL) {
 
 3958  if ((*connector)->connection == NULL) {
 
 3963  (*connector)->backend = backend;
 
 3964  (*connector)->bf = bf;
 
 3969  if ((*connector)->status_url) {
 
 3970    free((*connector)->status_url);
 
 3971    (*connector)->status_url = NULL;
 
 3974  if ((*connector)->api_url) {
 
 3975    free((*connector)->api_url);
 
 3976    (*connector)->api_url = NULL;
 
 3987static void destroy_connector(
yh_connector *connector) {
 
 3989  if (connector == NULL) {
 
 3993  if (connector->
bf != NULL && connector->
connection != NULL) {
 
 3994    connector->
bf->backend_disconnect(connector->
connection);
 
 4003  if (connector->
api_url != NULL) {
 
 4008  if (connector->
bf) {
 
 4009    connector->
bf->backend_cleanup();
 
 4012    FreeLibrary(connector->
backend);
 
 4018    connector->
bf = NULL;
 
 4025  if (
url == NULL || connector == NULL) {
 
 4026    DBG_ERR(
"Invalid parameters: undefined pointer");
 
 4031#define USB_LIB STATIC_USB_BACKEND 
 4032#define HTTP_LIB STATIC_HTTP_BACKEND 
 4034#define USB_LIB "libyubihsm_usb.dll" 
 4035#define HTTP_LIB "libyubihsm_http.dll" 
 4036#elif defined __APPLE__ 
 4037#define USB_LIB "libyubihsm_usb." SOVERSION ".dylib" 
 4038#define HTTP_LIB "libyubihsm_http." SOVERSION ".dylib" 
 4040#define USB_LIB "libyubihsm_usb.so." SOVERSION 
 4041#define HTTP_LIB "libyubihsm_http.so." SOVERSION 
 4044  void *backend = NULL;
 
 4049    load_backend(
USB_LIB, &backend, &bf);
 
 4050  } 
else if (strncmp(
url, 
"http://", strlen(
"http://")) == 0 ||
 
 4051             strncmp(
url, 
"https://", strlen(
"https://")) == 0) {
 
 4053    load_backend(
HTTP_LIB, &backend, &bf);
 
 4056    DBG_ERR(
"Failed loading the backend");
 
 4060  return create_connector(connector, 
url, backend, bf);
 
 
 4066  if (connector == NULL || val == NULL) {
 
 4067    DBG_ERR(
"Invalid parameters: undefined pointer");
 
 4071  if (connector->
bf == NULL) {
 
 4076  return connector->
bf->backend_option(connector->
connection, opt, val);
 
 
 4081  if (connector == NULL || connector->
bf == NULL) {
 
 4082    DBG_ERR(
"Invalid parameters: undefined pointer");
 
 4088  rc = connector->
bf->backend_connect(connector, timeout);
 
 
 4099  if (connector == NULL) {
 
 4104  destroy_connector(connector);
 
 
 4113     : ((uint64_t) htonl((x) &0xFFFFFFFF) << 32) | htonl((x) >> 32)) 
 
 4119  char *saveptr = NULL;
 
 4121  char tmp[2048] = {0};
 
 4124  if (capability == NULL || result == NULL) {
 
 4130  value = strtoull(capability, &endptr, 0);
 
 4132  if (capability != endptr && errno != ERANGE) {
 
 4134    memcpy(result, &actual, 8);
 
 4138  if (strcasecmp(capability, 
"all") == 0) {
 
 4141  } 
else if (strcasecmp(capability, 
"none") == 0) {
 
 4146  if (strlen(capability) > 
sizeof(tmp)) {
 
 4149  strncpy(tmp, capability, 
sizeof(tmp) - 1);
 
 4151  while ((str = strtok_r(str ? NULL : tmp, 
LIST_SEPARATORS, &saveptr))) {
 
 4152    for (
size_t i = 0; i < 
sizeof(yh_capability) / 
sizeof(yh_capability[0]);
 
 4154      if (strcasecmp(str, yh_capability[i].
name) == 0) {
 
 4157          1ULL << (yh_capability[i].bit % 8);
 
 4159      } 
else if (i + 1 == 
sizeof(yh_capability) / 
sizeof(yh_capability[0])) {
 
 
 4169                                 const char *result[], 
size_t *n_result) {
 
 4171  if (num == 0 || result == NULL || n_result == NULL) {
 
 4176  size_t matching = 0;
 
 4178  for (
size_t i = 0; i < 
sizeof(yh_capability) / 
sizeof(yh_capability[0]);
 
 4180    if (((1ULL << (yh_capability[i].
bit % 8)) &
 
 4182                           (yh_capability[i].bit / 8)]) != 0) {
 
 4183      if (++matching > *n_result) {
 
 4184        memset(result, 0, *n_result);
 
 4189      result[matching - 1] = yh_capability[i].name;
 
 4193  *n_result = matching;
 
 
 4199                         const char *capability) {
 
 
 4221  if (
a == NULL || b == NULL || result == NULL) {
 
 4226    result->capabilities[i] = 
a->capabilities[i] | b->
capabilities[i];
 
 
 4234  if (
capabilities == NULL || filter == NULL || result == NULL) {
 
 4239    result->capabilities[i] =
 
 
 4311  if (result == NULL) {
 
 
 4386  if (result == NULL) {
 
 4391  for (
size_t i = 0; i < 
sizeof(yh_algorithms) / 
sizeof(yh_algorithms[0]);
 
 4393    if (algo == yh_algorithms[i].
algorithm) {
 
 4394      *result = yh_algorithms[i].name;
 
 4399  *result = 
"Unknown";
 
 
 4405  if (
string == NULL || algo == NULL) {
 
 4409  if (strcasecmp(
string, 
"any") == 0) {
 
 4413  for (
size_t i = 0; i < 
sizeof(yh_algorithms) / 
sizeof(yh_algorithms[0]);
 
 4415    if (strcasecmp(
string, yh_algorithms[i].
name) == 0) {
 
 4416      *algo = yh_algorithms[i].algorithm;
 
 
 4426  if (result == NULL) {
 
 4431  for (
size_t i = 0; i < 
sizeof(yh_types) / 
sizeof(yh_types[0]); i++) {
 
 4432    if (type == yh_types[i].type) {
 
 4433      *result = yh_types[i].name;
 
 4438  *result = 
"Unknown";
 
 
 4444  if (
string == NULL || type == NULL) {
 
 4449  if (strcasecmp(
string, 
"any") == 0) {
 
 4453  for (
size_t i = 0; i < 
sizeof(yh_types) / 
sizeof(yh_types[0]); i++) {
 
 4454    if (strcasecmp(
string, yh_types[i].
name) == 0) {
 
 4455      *type = yh_types[i].type;
 
 
 4465  if (
string == NULL || 
option == NULL) {
 
 4470  for (
size_t i = 0; i < 
sizeof(yh_options) / 
sizeof(yh_options[0]); i++) {
 
 4471    if (strcasecmp(
string, yh_options[i].
name) == 0) {
 
 4472      *
option = yh_options[i].option;
 
 
 4482  if (logs == NULL || n_items == 0) {
 
 4488  size_t previous_hash_len = 32;
 
 4496  if (last_previous_log != NULL) {
 
 4504  for (
uint16_t i = start; i < n_items; i++) {
 
 4506    inverted.
number = htons(logs[i].number);
 
 4508    inverted.
length = htons(logs[i].length);
 
 4509    inverted.
session_key = htons(logs[i].session_key);
 
 4510    inverted.
target_key = htons(logs[i].target_key);
 
 4511    inverted.
second_key = htons(logs[i].second_key);
 
 4513    inverted.
systick = htonl(logs[i].systick);
 
 4519    hash_final(hashctx, previous_hash, &previous_hash_len);
 
 
 4537  char *saveptr = NULL;
 
 4540  unsigned long value;
 
 4542  if (
domains == NULL || result == NULL) {
 
 4548  if (strcasecmp(
domains, 
"all") == 0) {
 
 4551  } 
else if (strcmp(
domains, 
"0") == 0) {
 
 4558  if (strncmp(
domains, 
"0x", 2) == 0 && *endptr == 
'\0' && errno != ERANGE &&
 
 4559      value != ULONG_MAX) {
 
 4560    if (
value > USHRT_MAX) {
 
 4561      DBG_ERR(
"Tried to parse to long number for domains");
 
 4566    if (strlen(
domains) > 
sizeof(tmp)) {
 
 4569    strncpy(tmp, 
domains, 
sizeof(tmp) - 1);
 
 4571    while ((str = strtok_r(str ? NULL : tmp, 
LIST_SEPARATORS, &saveptr))) {
 
 4573      value = strtoul(str, &endptr, 0);
 
 4578      *result |= 1 << (
value - 1);
 
 4583  DBG_INFO(
"Domains parsed as %x", *result);
 
 
 4592      size_t wrote = snprintf(ptr, max_len, 
"%d:", i + 1);
 
 4593      if (wrote >= max_len) {
 
 4600  if (ptr != 
string) {
 
 
void aes_remove_padding(uint8_t *in, uint16_t *len)
 
uint8_t aes_set_encrypt_key(uint8_t *key, uint16_t key_len, aes_context *ctx)
 
void aes_destroy(aes_context *ctx)
 
uint8_t aes_encrypt(uint8_t *in, uint8_t *out, const aes_context *ctx)
 
uint8_t aes_cbc_decrypt(uint8_t *in, uint8_t *out, uint16_t len, uint8_t *iv, aes_context *ctx)
 
void aes_add_padding(uint8_t *in, uint16_t *len)
 
uint8_t aes_set_decrypt_key(uint8_t *key, uint16_t key_len, aes_context *ctx)
 
uint8_t aes_cbc_encrypt(uint8_t *in, uint8_t *out, uint16_t len, uint8_t *iv, aes_context *ctx)
 
uint8_t aes_cmac_init(uint8_t *key, uint16_t key_len, aes_cmac_context_t *ctx)
 
void aes_cmac_destroy(aes_cmac_context_t *ctx)
 
void aes_cmac_encrypt(const aes_cmac_context_t *ctx, const uint8_t *message, const uint16_t message_len, uint8_t *mac)
 
#define DBG_CRYPTO(var, len,...)
 
#define DBG_DUMPERR(var, len,...)
 
#define DBG_NET(var, dump)
 
#define DBG_INT(var, len,...)
 
#define DBG_DUMPINFO(var, len,...)
 
CK_SESSION_HANDLE session
 
bool hash_update(_hash_ctx *ctx, const uint8_t *in, size_t cb_in)
 
bool hash_create(_hash_ctx **ctx, hash_t hash)
 
bool hash_init(_hash_ctx *ctx)
 
bool hash_destroy(_hash_ctx *ctx)
 
bool hash_final(_hash_ctx *ctx, uint8_t *out, size_t *pcb_out)
 
#define insecure_memzero(buf, len)
 
const char * yh_strerror(yh_rc err)
 
void YH_INTERNAL dump_response(FILE *file, const Msg *msg)
 
void YH_INTERNAL dump_msg(FILE *file, const Msg *msg)
 
struct sysio::chain::eosvmoc::code_cache_header __attribute__((packed))
 
bool pkcs5_pbkdf2_hmac(const uint8_t *password, size_t cb_password, const uint8_t *salt, size_t cb_salt, uint64_t iterations, hash_t hash, uint8_t *key, size_t cb_key)
 
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
 
bool rand_generate(uint8_t *buf, size_t cb_buf)
 
#define SCP_S_RMAC_DERIVATION
 
#define SCP_CARD_CRYPTOGRAM
 
#define SCP_S_MAC_DERIVATION
 
#define SCP_CARD_CHAL_LEN
 
#define SCP_S_ENC_DERIVATION
 
#define SCP_AUTHKEY_ID_LEN
 
#define SCP_HOST_CRYPTO_LEN
 
#define SCP_HOST_CHAL_LEN
 
#define SCP_HOST_CRYPTOGRAM
 
#define SCP_CARD_CRYPTO_LEN
 
unsigned __int64 uint64_t
 
uint8_t s_mac[SCP_KEY_LEN]
 
uint8_t s_rmac[SCP_KEY_LEN]
 
uint8_t s_enc[SCP_KEY_LEN]
 
yh_backend *(* backend_create)(void)
 
Capabilities representation.
 
uint8_t capabilities[YH_CAPABILITIES_LEN]
Capabilities is represented as an 8 byte uint8_t array.
 
struct backend_functions * bf
 
uint8_t digest[YH_LOG_DIGEST_SIZE]
Truncated sha256 digest of this last digest + this entry.
 
uint16_t second_key
ID of second Object used.
 
uint8_t result
Command result.
 
uint32_t systick
Systick at time of execution.
 
uint16_t session_key
ID of Authentication Key used.
 
uint16_t target_key
ID of first Object used.
 
uint16_t length
Length of in-data.
 
uint8_t command
What command was executed.
 
uint16_t number
Monotonically increasing index.
 
uint8_t sequence
Object sequence.
 
yh_capabilities capabilities
Object capabilities.
 
yh_capabilities delegated_capabilities
Object delegated capabilities.
 
char label[YH_OBJ_LABEL_LEN+1]
Object label.
 
yh_object_type type
Object type.
 
uint8_t key_enc[SCP_KEY_LEN]
 
struct yh_connector * parent
 
uint8_t key_mac[SCP_KEY_LEN]
 
uint8_t context[SCP_CONTEXT_LEN]
 
uint8_t raw[3+SCP_MSG_BUF_SIZE]
 
bool yh_verify_logs(yh_log_entry *logs, size_t n_items, yh_log_entry *last_previous_log)
 
yh_rc yh_domains_to_string(uint16_t domains, char *string, size_t max_len)
 
bool yh_is_rsa(yh_algorithm algorithm)
 
yh_rc yh_create_session(yh_connector *connector, uint16_t authkey_id, const uint8_t *key_enc, size_t key_enc_len, const uint8_t *key_mac, size_t key_mac_len, bool recreate, yh_session **session)
 
yh_rc yh_util_get_option(yh_session *session, yh_option option, uint8_t *out, size_t *out_len)
 
yh_rc yh_util_import_opaque(yh_session *session, uint16_t *object_id, const char *label, uint16_t domains, const yh_capabilities *capabilities, yh_algorithm algorithm, const uint8_t *in, size_t in_len)
 
bool yh_connector_has_device(yh_connector *connector)
 
bool yh_is_ed(yh_algorithm algorithm)
 
yh_rc yh_get_verbosity(uint8_t *verbosity)
 
yh_rc yh_util_import_hmac_key(yh_session *session, uint16_t *key_id, const char *label, uint16_t domains, const yh_capabilities *capabilities, yh_algorithm algorithm, const uint8_t *key, size_t key_len)
 
yh_rc yh_destroy_session(yh_session **session)
 
yh_rc yh_util_generate_hmac_key(yh_session *session, uint16_t *key_id, const char *label, uint16_t domains, const yh_capabilities *capabilities, yh_algorithm algorithm)
 
yh_rc yh_util_generate_wrap_key(yh_session *session, uint16_t *key_id, const char *label, uint16_t domains, const yh_capabilities *capabilities, yh_algorithm algorithm, const yh_capabilities *delegated_capabilities)
 
yh_rc yh_set_verbosity(yh_connector *connector, uint8_t verbosity)
 
yh_rc yh_util_derive_ecdh(yh_session *session, uint16_t key_id, const uint8_t *in, size_t in_len, uint8_t *out, size_t *out_len)
 
yh_rc yh_begin_create_session_ext(yh_connector *connector, uint16_t authkey_id, uint8_t **context, uint8_t *card_cryptogram, size_t card_cryptogram_len, yh_session **session)
 
yh_rc yh_algo_to_string(yh_algorithm algo, char const **result)
 
yh_rc yh_get_connector_version(yh_connector *connector, uint8_t *major, uint8_t *minor, uint8_t *patch)
 
yh_rc yh_util_generate_ec_key(yh_session *session, uint16_t *key_id, const char *label, uint16_t domains, const yh_capabilities *capabilities, yh_algorithm algorithm)
 
bool yh_is_ec(yh_algorithm algorithm)
 
yh_rc yh_util_decrypt_otp(yh_session *session, uint16_t key_id, const uint8_t *aead, size_t aead_len, const uint8_t *otp, uint16_t *useCtr, uint8_t *sessionCtr, uint8_t *tstph, uint16_t *tstpl)
 
yh_rc yh_get_key_bitlength(yh_algorithm algorithm, size_t *result)
 
yh_rc yh_util_import_wrap_key(yh_session *session, uint16_t *key_id, const char *label, uint16_t domains, const yh_capabilities *capabilities, yh_algorithm algorithm, const yh_capabilities *delegated_capabilities, const uint8_t *in, size_t in_len)
 
yh_rc yh_create_session_derived(yh_connector *connector, uint16_t authkey_id, const uint8_t *password, size_t password_len, bool recreate, yh_session **session)
 
yh_rc yh_util_generate_ed_key(yh_session *session, uint16_t *key_id, const char *label, uint16_t domains, const yh_capabilities *capabilities, yh_algorithm algorithm)
 
yh_rc yh_util_sign_ssh_certificate(yh_session *session, uint16_t key_id, uint16_t template_id, yh_algorithm sig_algo, const uint8_t *in, size_t in_len, uint8_t *out, size_t *out_len)
 
yh_rc yh_util_get_template(yh_session *session, uint16_t object_id, uint8_t *out, size_t *out_len)
 
yh_rc yh_util_randomize_otp_aead(yh_session *session, uint16_t key_id, uint8_t *out, size_t *out_len)
 
yh_rc yh_send_secure_msg(yh_session *session, yh_cmd cmd, const uint8_t *data, size_t data_len, yh_cmd *response_cmd, uint8_t *response, size_t *response_len)
 
yh_rc yh_util_sign_ecdsa(yh_session *session, uint16_t key_id, const uint8_t *in, size_t in_len, uint8_t *out, size_t *out_len)
 
uint8_t _yh_verbosity YH_INTERNAL
 
yh_rc yh_string_to_option(const char *string, yh_option *option)
 
yh_rc yh_util_unwrap_data(yh_session *session, uint16_t key_id, const uint8_t *in, size_t in_len, uint8_t *out, size_t *out_len)
 
yh_rc yh_util_get_opaque(yh_session *session, uint16_t object_id, uint8_t *out, size_t *out_len)
 
yh_rc yh_string_to_type(const char *string, yh_object_type *type)
 
yh_rc yh_util_sign_attestation_certificate(yh_session *session, uint16_t key_id, uint16_t attest_id, uint8_t *out, size_t *out_len)
 
yh_rc yh_util_get_log_entries(yh_session *session, uint16_t *unlogged_boot, uint16_t *unlogged_auth, yh_log_entry *out, size_t *n_items)
 
yh_rc yh_util_reset_device(yh_session *session)
 
yh_rc yh_util_decrypt_pkcs1v1_5(yh_session *session, uint16_t key_id, const uint8_t *in, size_t in_len, uint8_t *out, size_t *out_len)
 
yh_rc yh_util_close_session(yh_session *session)
 
yh_rc yh_util_sign_eddsa(yh_session *session, uint16_t key_id, const uint8_t *in, size_t in_len, uint8_t *out, size_t *out_len)
 
yh_rc yh_util_get_device_info(yh_connector *connector, uint8_t *major, uint8_t *minor, uint8_t *patch, uint32_t *serial, uint8_t *log_total, uint8_t *log_used, yh_algorithm *algorithms, size_t *n_algorithms)
 
yh_rc yh_authenticate_session(yh_session *session)
 
yh_rc yh_send_plain_msg(yh_connector *connector, yh_cmd cmd, const uint8_t *data, size_t data_len, yh_cmd *response_cmd, uint8_t *response, size_t *response_len)
 
yh_rc yh_util_import_ed_key(yh_session *session, uint16_t *key_id, const char *label, uint16_t domains, const yh_capabilities *capabilities, yh_algorithm algorithm, const uint8_t *k)
 
yh_rc yh_util_get_object_info(yh_session *session, uint16_t id, yh_object_type type, yh_object_descriptor *object)
 
yh_rc yh_util_wrap_data(yh_session *session, uint16_t key_id, const uint8_t *in, size_t in_len, uint8_t *out, size_t *out_len)
 
yh_rc yh_util_list_objects(yh_session *session, uint16_t id, yh_object_type type, uint16_t domains, const yh_capabilities *capabilities, yh_algorithm algorithm, const char *label, yh_object_descriptor *objects, size_t *n_objects)
 
void yh_set_debug_output(yh_connector *connector, FILE *output)
 
yh_rc yh_util_import_authentication_key_derived(yh_session *session, uint16_t *key_id, const char *label, uint16_t domains, const yh_capabilities *capabilities, const yh_capabilities *delegated_capabilities, const uint8_t *password, size_t password_len)
 
yh_rc yh_util_create_otp_aead(yh_session *session, uint16_t key_id, const uint8_t *key, const uint8_t *private_id, uint8_t *out, size_t *out_len)
 
yh_rc yh_util_set_option(yh_session *session, yh_option option, size_t len, uint8_t *val)
 
yh_rc yh_util_change_authentication_key_derived(yh_session *session, uint16_t *key_id, const uint8_t *password, size_t password_len)
 
yh_rc yh_util_change_authentication_key(yh_session *session, uint16_t *key_id, const uint8_t *key_enc, size_t key_enc_len, const uint8_t *key_mac, size_t key_mac_len)
 
yh_rc yh_filter_capabilities(const yh_capabilities *capabilities, const yh_capabilities *filter, yh_capabilities *result)
 
yh_rc yh_util_sign_hmac(yh_session *session, uint16_t key_id, const uint8_t *in, size_t in_len, uint8_t *out, size_t *out_len)
 
yh_rc yh_util_sign_pss(yh_session *session, uint16_t key_id, const uint8_t *in, size_t in_len, uint8_t *out, size_t *out_len, size_t salt_len, yh_algorithm mgf1Algo)
 
yh_rc yh_string_to_domains(const char *domains, uint16_t *result)
 
yh_rc yh_set_connector_option(yh_connector *connector, yh_connector_option opt, const void *val)
 
yh_rc yh_init_connector(const char *url, yh_connector **connector)
 
yh_rc yh_util_set_log_index(yh_session *session, uint16_t index)
 
yh_rc yh_util_generate_otp_aead_key(yh_session *session, uint16_t *key_id, const char *label, uint16_t domains, const yh_capabilities *capabilities, yh_algorithm algorithm, uint32_t nonce_id)
 
yh_rc yh_util_sign_pkcs1v1_5(yh_session *session, uint16_t key_id, bool hashed, const uint8_t *in, size_t in_len, uint8_t *out, size_t *out_len)
 
yh_rc yh_connect(yh_connector *connector, int timeout)
 
yh_rc yh_util_export_wrapped(yh_session *session, uint16_t wrapping_key_id, yh_object_type target_type, uint16_t target_id, uint8_t *out, size_t *out_len)
 
yh_rc yh_util_get_public_key(yh_session *session, uint16_t id, uint8_t *data, size_t *data_len, yh_algorithm *algorithm)
 
yh_rc yh_util_decrypt_oaep(yh_session *session, uint16_t key_id, const uint8_t *in, size_t in_len, uint8_t *out, size_t *out_len, const uint8_t *label, size_t label_len, yh_algorithm mgf1Algo)
 
yh_rc yh_string_to_capabilities(const char *capability, yh_capabilities *result)
 
yh_rc yh_string_to_algo(const char *string, yh_algorithm *algo)
 
yh_rc yh_util_import_rsa_key(yh_session *session, uint16_t *key_id, const char *label, uint16_t domains, const yh_capabilities *capabilities, yh_algorithm algorithm, const uint8_t *p, const uint8_t *q)
 
yh_rc yh_disconnect(yh_connector *connector)
 
yh_rc yh_util_generate_rsa_key(yh_session *session, uint16_t *key_id, const char *label, uint16_t domains, const yh_capabilities *capabilities, yh_algorithm algorithm)
 
yh_rc yh_util_verify_hmac(yh_session *session, uint16_t key_id, const uint8_t *signature, size_t signature_len, const uint8_t *data, size_t data_len, bool *verified)
 
bool yh_check_capability(const yh_capabilities *capabilities, const char *capability)
 
#define STATIC_HTTP_BACKEND
 
yh_rc yh_util_import_authentication_key(yh_session *session, uint16_t *key_id, const char *label, uint16_t domains, const yh_capabilities *capabilities, const yh_capabilities *delegated_capabilities, const uint8_t *key_enc, size_t key_enc_len, const uint8_t *key_mac, size_t key_mac_len)
 
yh_rc yh_capabilities_to_strings(const yh_capabilities *num, const char *result[], size_t *n_result)
 
#define STATIC_USB_BACKEND
 
bool yh_is_hmac(yh_algorithm algorithm)
 
yh_rc yh_get_connector_address(yh_connector *connector, char **const address)
 
yh_rc yh_util_blink_device(yh_session *session, uint8_t seconds)
 
#define LIST_CAPABILITIES
 
yh_rc yh_util_import_ec_key(yh_session *session, uint16_t *key_id, const char *label, uint16_t domains, const yh_capabilities *capabilities, yh_algorithm algorithm, const uint8_t *s)
 
yh_rc yh_util_import_otp_aead_key(yh_session *session, uint16_t *key_id, const char *label, uint16_t domains, const yh_capabilities *capabilities, uint32_t nonce_id, const uint8_t *in, size_t in_len)
 
yh_rc yh_util_import_template(yh_session *session, uint16_t *object_id, const char *label, uint16_t domains, const yh_capabilities *capabilities, yh_algorithm algorithm, const uint8_t *in, size_t in_len)
 
yh_rc yh_util_import_wrapped(yh_session *session, uint16_t wrapping_key_id, const uint8_t *in, size_t in_len, yh_object_type *target_type, uint16_t *target_id)
 
yh_rc yh_util_delete_object(yh_session *session, uint16_t id, yh_object_type type)
 
yh_rc yh_util_get_storage_info(yh_session *session, uint16_t *total_records, uint16_t *free_records, uint16_t *total_pages, uint16_t *free_pages, uint16_t *page_size)
 
yh_rc yh_get_session_id(yh_session *session, uint8_t *sid)
 
yh_rc yh_util_get_pseudo_random(yh_session *session, size_t len, uint8_t *out, size_t *out_len)
 
yh_rc yh_finish_create_session_ext(yh_connector *connector, yh_session *session, const uint8_t *key_senc, size_t key_senc_len, const uint8_t *key_smac, size_t key_smac_len, const uint8_t *key_srmac, size_t key_srmac_len, uint8_t *card_cryptogram, size_t card_cryptogram_len)
 
yh_rc yh_merge_capabilities(const yh_capabilities *a, const yh_capabilities *b, yh_capabilities *result)
 
yh_rc yh_type_to_string(yh_object_type type, char const **result)
 
#define YH_DEFAULT_ITERS
Number of iterations for PBKDF2 key derivation.
 
#define YH_LOG_DIGEST_SIZE
Size that the log digest is truncated to.
 
#define YH_HOST_CHAL_LEN
Length of host challenge for authentication.
 
#define YH_OBJ_LABEL_LEN
Max length of object labels.
 
@ YH_ALGO_EC_BP384
ecbp384
 
@ YH_ALGO_AES128_YUBICO_AUTHENTICATION
aes128-yubico-authentication
 
@ YH_ALGO_AES192_YUBICO_OTP
aes192-yubico-otp
 
@ YH_ALGO_AES128_YUBICO_OTP
aes128-yubico-otp
 
@ YH_ALGO_EC_ED25519
ed25519
 
@ YH_ALGO_HMAC_SHA512
hmac-sha512
 
@ YH_ALGO_HMAC_SHA384
hmac-sha384
 
@ YH_ALGO_AES256_CCM_WRAP
aes256-ccm-wrap
 
@ YH_ALGO_HMAC_SHA1
hmac-sha1
 
@ YH_ALGO_RSA_2048
rsa2048
 
@ YH_ALGO_HMAC_SHA256
hmac-sha256
 
@ YH_ALGO_AES192_CCM_WRAP
aes192-ccm-wrap
 
@ YH_ALGO_EC_BP512
ecbp512
 
@ YH_ALGO_EC_BP256
ecbp256
 
@ YH_ALGO_AES256_YUBICO_OTP
aes256-yubico-otp
 
@ YH_ALGO_AES128_CCM_WRAP
aes128-ccm-wrap
 
@ YH_ALGO_RSA_4096
rsa4096
 
@ YH_ALGO_RSA_3072
rsa3072
 
#define YH_USB_URL_SCHEME
URL scheme used for direct USB access.
 
#define YH_MAX_ALGORITHM_COUNT
Max number of algorithms defined here.
 
#define YH_MSG_BUF_SIZE
Maximum length of message buffer.
 
#define YH_DEFAULT_SALT
Salt to be used for PBKDF2 key derivation.
 
#define YH_KEY_LEN
Length of authentication keys.
 
#define YH_CAPABILITIES_LEN
Length of capabilities array.
 
#define YH_MAX_LOG_ENTRIES
Max log entries the device may hold.
 
@ YHR_DEVICE_INSUFFICIENT_PERMISSIONS
Return value when the permissions to perform the operation are wrong.
 
@ YHR_DEVICE_INVALID_SESSION
Returned value when the device session is invalid.
 
@ YHR_GENERIC_ERROR
Return value when encountering an unknown error.
 
@ YHR_SUCCESS
Returned value when function was successful.
 
@ YHR_DEVICE_COMMAND_UNEXECUTED
Return value when the command execution has not terminated.
 
@ YHR_INVALID_PARAMETERS
Returned value when an argument to a function is invalid.
 
@ YHR_MEMORY_ERROR
Returned value when unable to allocate memory.
 
@ YHR_DEVICE_INVALID_COMMAND
Returned value when the device receives and invalid command.
 
@ YHR_DEVICE_SESSIONS_FULL
Return value when no more sessions can be opened on the device.
 
@ YHR_DEVICE_SESSION_FAILED
Return value when failing to create a device session.
 
@ YHR_DEVICE_OBJECT_NOT_FOUND
Return value when the object not found on the device.
 
@ YHR_DEVICE_AUTHENTICATION_FAILED
Return value when the device fails to encrypt or verify the message.
 
@ YHR_DEVICE_LOG_FULL
Return value when the log buffer is full and forced audit is set.
 
@ YHR_DEVICE_INVALID_OTP
Return value when an invalid OTP is submitted.
 
@ YHR_DEVICE_DEMO_MODE
Return value when the device is in demo mode and has to be power cycled.
 
@ YHR_DEVICE_INVALID_DATA
Returned value when the device receives a malformed command invalid data.
 
@ YHR_DEVICE_STORAGE_FAILED
Return value when encountering a storage failure on the device.
 
@ YHR_DEVICE_OBJECT_EXISTS
Return value when trying to add an object with an ID that already exists.
 
@ YHR_BUFFER_TOO_SMALL
Returned value when there is not enough space to store data.
 
@ YHR_MAC_MISMATCH
Returned value when failing to verify MAC.
 
@ YHR_DEVICE_WRONG_LENGTH
 
@ YHR_CONNECTION_ERROR
Returned value when a connection error was encountered.
 
@ YHR_DEVICE_SSH_CA_CONSTRAINT_VIOLATION
Return value when encountering SSH CA constraint violation.
 
@ YHR_DEVICE_OK
Returned value when the device returned no error.
 
@ YHR_DEVICE_INVALID_ID
Return value when an invalid Object ID is used.
 
@ YHR_SESSION_AUTHENTICATION_FAILED
Returned value when failing to authenticate the session.
 
@ YHR_CRYPTOGRAM_MISMATCH
Returned value when failing to verify cryptogram.
 
#define YH_MAX_DOMAINS
Max number of domains.
 
#define YH_CONTEXT_LEN
Length of context array for authentication.
 
struct backend_functions * backend_functions(void)
 
yh_capabilities capabilities
 
yh_object_type target_type
 
session operation op find n_objects
 
yh_object_descriptor object
 
session operation op sign key_len
 
memset(pInfo->slotDescription, ' ', 64)
 
memcpy((char *) pInfo->slotDescription, s, l)
 
yh_capabilities delegated_capabilities