Пример #1
0
/**
 * 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);
}
Пример #2
0
/**
 * 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;
}