/** * generate HIP keying material * @param kij Diffie-Hellman Kij (as in the HIP drafts) * @param kij_len the length of the Kij material * @param keymat pointer to a keymat structure which will be updated according * to the generated keymaterial * @param dstbuf the generated keymaterial will be written here * @param dstbuflen the length of the buffer to which to write to * @param hit1 source HIT * @param hit2 destination HIT * @param calc_index where the one byte index is stored (n of Kn) * @param I the I value * @param J the J value * */ void hip_make_keymat(char *kij, size_t kij_len, struct hip_keymat_keymat *keymat, void *dstbuf, size_t dstbuflen, struct in6_addr *hit1, struct in6_addr *hit2, uint8_t *calc_index, const uint8_t I[PUZZLE_LENGTH], const uint8_t J[PUZZLE_LENGTH]) { int bufsize; uint8_t index_nbr = 1; size_t dstoffset = 0; void *seedkey; struct in6_addr *smaller_hit, *bigger_hit; int hit1_is_bigger; uint8_t *shabuffer = NULL; HIP_DEBUG("\n"); if (dstbuflen < HIP_AH_SHA_LEN) { HIP_ERROR("dstbuf is too short (%d)\n", dstbuflen); return; } HIP_ASSERT(sizeof(index_nbr) == HIP_KEYMAT_INDEX_NBR_SIZE); hit1_is_bigger = hip_hit_is_bigger(hit1, hit2); bigger_hit = hit1_is_bigger ? hit1 : hit2; smaller_hit = hit1_is_bigger ? hit2 : hit1; shabuffer = hip_create_keymat_buffer(kij, kij_len, HIP_AH_SHA_LEN, smaller_hit, bigger_hit, I, J); if (!shabuffer) { HIP_ERROR("No memory for keymat\n"); return; } bufsize = kij_len + 2 * sizeof(struct in6_addr) + 2 * sizeof(uint64_t) + 1; // XX FIXME: is this correct hip_build_digest(HIP_DIGEST_SHA1, shabuffer, bufsize, dstbuf); dstoffset = HIP_AH_SHA_LEN; index_nbr++; /* * K2 = SHA1(Kij | K1 | 2) * K3 = SHA1(Kij | K2 | 3) * ... */ seedkey = dstbuf; hip_update_keymat_buffer(shabuffer, seedkey, HIP_AH_SHA_LEN, kij_len, index_nbr); while (dstoffset < dstbuflen) { hip_build_digest(HIP_DIGEST_SHA1, shabuffer, kij_len + HIP_AH_SHA_LEN + 1, (uint8_t *) dstbuf + dstoffset); seedkey = (uint8_t *) dstbuf + dstoffset; dstoffset += HIP_AH_SHA_LEN; index_nbr++; hip_update_keymat_buffer(shabuffer, seedkey, HIP_AH_SHA_LEN, kij_len, index_nbr); } keymat->offset = 0; keymat->keymatlen = dstoffset; keymat->keymatdst = dstbuf; if (calc_index) { *calc_index = index_nbr; } else { HIP_ERROR("NULL calc_index\n"); } free(shabuffer); }
/** * hip_make_keymat - generate HIP keying material * @param kij Diffie-Hellman Kij (as in the HIP drafts) * @param kij_len the length of the Kij material * @param keymat pointer to a keymat structure which will be updated according * to the generated keymaterial * @param dstbuf the generated keymaterial will be written here * @param hit1 source HIT * @param hit2 destination HIT * @param calc_index where the one byte index is stored (n of Kn) * */ void hip_make_keymat(char *kij, size_t kij_len, struct hip_keymat_keymat *keymat, void *dstbuf, size_t dstbuflen, struct in6_addr *hit1, struct in6_addr *hit2, u8 *calc_index, uint64_t I, uint64_t J) { int bufsize, err = 0; uint8_t index_nbr = 1; int dstoffset = 0; void *seedkey; struct in6_addr *smaller_hit, *bigger_hit; int hit1_is_bigger; u8 *shabuffer = NULL; HIP_DEBUG("\n"); if (dstbuflen < HIP_AH_SHA_LEN) { HIP_ERROR("dstbuf is too short (%d)\n", dstbuflen); return; } _HIP_ASSERT(dstbuflen % 32 == 0); HIP_ASSERT(sizeof(index_nbr) == HIP_KEYMAT_INDEX_NBR_SIZE); hit1_is_bigger = hip_hit_is_bigger(hit1, hit2); bigger_hit = hit1_is_bigger ? hit1 : hit2; smaller_hit = hit1_is_bigger ? hit2 : hit1; _HIP_HEXDUMP("kij", kij, kij_len); _HIP_DEBUG("I=0x%llx J=0x%llx\n", I, J); _HIP_HEXDUMP("bigger hit", bigger_hit, 16); _HIP_HEXDUMP("smaller hit", smaller_hit, 16); _HIP_HEXDUMP("index_nbr", (char *) &index_nbr, HIP_KEYMAT_INDEX_NBR_SIZE); shabuffer = hip_create_keymat_buffer(kij, kij_len, HIP_AH_SHA_LEN, smaller_hit, bigger_hit, I, J); if (!shabuffer) { HIP_ERROR("No memory for keymat\n"); return; } bufsize = kij_len + 2 * sizeof(struct in6_addr) + 2 * sizeof(uint64_t) + 1; //bufsize = kij_len+2*sizeof(struct in6_addr)+ 1; // XX FIXME: is this correct hip_build_digest(HIP_DIGEST_SHA1, shabuffer, bufsize, dstbuf); _HIP_HEXDUMP("keymat digest", dstbuf, HIP_AH_SHA_LEN); dstoffset = HIP_AH_SHA_LEN; index_nbr++; /* * K2 = SHA1(Kij | K1 | 2) * K3 = SHA1(Kij | K2 | 3) * ... */ seedkey = dstbuf; hip_update_keymat_buffer(shabuffer, seedkey, HIP_AH_SHA_LEN, kij_len, index_nbr); while (dstoffset < dstbuflen) { hip_build_digest(HIP_DIGEST_SHA1, shabuffer, kij_len + HIP_AH_SHA_LEN + 1, dstbuf + dstoffset); seedkey = dstbuf + dstoffset; dstoffset += HIP_AH_SHA_LEN; index_nbr++; hip_update_keymat_buffer(shabuffer, seedkey, HIP_AH_SHA_LEN, kij_len, index_nbr); } keymat->offset = 0; keymat->keymatlen = dstoffset; keymat->keymatdst = dstbuf; if (calc_index) *calc_index = index_nbr; else HIP_ERROR("NULL calc_index\n"); _HIP_DEBUG("keymat index_nbr=%u\n", index_nbr); _HIP_HEXDUMP("GENERATED KEYMAT: ", dstbuf, dstbuflen); if (shabuffer) HIP_FREE(shabuffer); return; }