/** * crypto_hash_data_key(key, keylen, data, len, buf): * Hash the provided data with the provided HMAC-SHA256 key. */ void crypto_hash_data_key(const uint8_t * key, size_t keylen, const uint8_t * data, size_t len, uint8_t buf[32]) { /* Use crypto_hash_data_key_2 to do the work. */ crypto_hash_data_key_2(key, keylen, data, len, NULL, 0, buf); }
/** * crypto_session_sign(CS, buf, buflen, sig): * Generate sig = write_auth(buf). */ void crypto_session_sign(CRYPTO_SESSION * CS, const uint8_t * buf, size_t buflen, uint8_t sig[32]) { uint8_t nonce[8]; /* Convert nonce to 8-byte big-endian format, and increment. */ be64enc(nonce, CS->auth_write_nonce); CS->auth_write_nonce += 1; /* Generate hash. */ crypto_hash_data_key_2(CS->auth_write, 32, nonce, 8, buf, buflen, sig); }
static int callback_register_response(void * cookie, NETPACKET_CONNECTION * NPC, int status, uint8_t packettype, const uint8_t * packetbuf, size_t packetlen) { struct register_internal * C = cookie; uint8_t hmac_actual[32]; (void)NPC; /* UNUSED */ (void)packetlen; /* UNUSED */ /* Handle errors. */ if (status != NETWORK_STATUS_OK) { netproto_printerr(status); goto err0; } /* Make sure we received the right type of packet. */ if (packettype != NETPACKET_REGISTER_RESPONSE) goto err1; /* Verify packet hmac. */ if ((packetbuf[0] == 0) || (packetbuf[0] == 3)) { crypto_hash_data_key_2(C->register_key, 32, &packettype, 1, packetbuf, 9, hmac_actual); } else { memset(hmac_actual, 0, 32); } if (crypto_verify_bytes(hmac_actual, &packetbuf[9], 32)) goto err1; /* Record status code and machine number returned by server. */ C->status = packetbuf[0]; C->machinenum = be64dec(&packetbuf[1]); /* We have received a response. */ C->done = 1; /* Success! */ return (0); err1: netproto_printerr(NETPROTO_STATUS_PROTERR); err0: /* Failure! */ return (-1); }
/** * netpacket_register_cha_response(NPC, keys, name, register_key, callback): * Construct and send a NETPACKET_REGISTER_CHA_RESPONSE packet providing the * given access keys and user-friendly name, signed using the shared key * ${register_key} computed by hashing the Diffie-Hellman shared secret K. */ int netpacket_register_cha_response(NETPACKET_CONNECTION * NPC, const uint8_t keys[96], const char * name, const uint8_t register_key[32], handlepacket_callback * callback) { size_t namelen; uint8_t * packetbuf; uint8_t prefixbuf[1]; /* Allocate temporary space for constructing packet. */ namelen = strlen(name); if ((packetbuf = malloc(129 + namelen)) == NULL) goto err0; /* Construct challenge response packet. */ memcpy(packetbuf, keys, 96); packetbuf[96] = (uint8_t)namelen; memcpy(packetbuf + 97, name, namelen); /* Append hmac. */ prefixbuf[0] = NETPACKET_REGISTER_CHA_RESPONSE; crypto_hash_data_key_2(register_key, 32, prefixbuf, 1, packetbuf, 97 + namelen, &packetbuf[97 + namelen]); /* Send challenge response packet. */ if (netproto_writepacket(NPC->NC, NETPACKET_REGISTER_CHA_RESPONSE, packetbuf, 129 + namelen, netpacket_op_packetsent, NPC)) goto err1; /* Set callback for handling a response. */ NPC->pending_current->handlepacket = callback; /* Free temporary packet buffer. */ free(packetbuf); /* Success! */ return (0); err1: free(packetbuf); err0: /* Failure! */ return (-1); }
/** * crypto_session_verify(CS, buf, buflen, sig): * Verify that sig = read_auth(buf). Return non-zero if the signature * does not match. */ int crypto_session_verify(CRYPTO_SESSION * CS, const uint8_t * buf, size_t buflen, const uint8_t sig[32]) { uint8_t nonce[8]; uint8_t sig_actual[32]; /* Convert nonce to 8-byte big-endian format, and increment. */ be64enc(nonce, CS->auth_read_nonce); CS->auth_read_nonce += 1; /* Generate hash. */ crypto_hash_data_key_2(CS->auth_read, 32, nonce, 8, buf, buflen, sig_actual); /* Determine if the signatures match. */ if (crypto_verify_bytes(sig, sig_actual, 32)) return (1); else return (0); }