/* * Generate a cookie (aka SPI) * First argument is true if we're to create an Initiator cookie. * Length SHOULD be a multiple of sizeof(u_int32_t). * * As responder, we use a hashing method to get a pseudo random * value instead of using our own random pool. It will prevent * an attacker from gaining raw data from our random pool and * it will prevent an attacker from depleting our random pool * or entropy. */ void get_cookie(bool initiator, u_int8_t cookie[COOKIE_SIZE], const ip_address *addr) { do { if (initiator) { get_rnd_bytes(cookie, COOKIE_SIZE); } else { static u_int32_t counter = 0; /* STATIC */ unsigned char addr_buff[ sizeof(union { struct in_addr A; struct in6_addr B; })]; u_char buffer[SHA2_256_DIGEST_SIZE]; sha256_context ctx; size_t addr_length = addrbytesof(addr, addr_buff, sizeof(addr_buff)); sha256_init(&ctx); sha256_write(&ctx, addr_buff, addr_length); sha256_write(&ctx, secret_of_the_day, sizeof(secret_of_the_day)); counter++; sha256_write(&ctx, (const void *) &counter, sizeof(counter)); sha256_final(buffer, &ctx); /* cookie size is smaller than any hash output sizes */ memcpy(cookie, buffer, COOKIE_SIZE); } } while (is_zero_cookie(cookie)); /* probably never loops */ }
/* Generate a cookie. * First argument is true if we're to create an Initiator cookie. * Length SHOULD be a multiple of sizeof(u_int32_t). */ void get_cookie(bool initiator, u_int8_t *cookie, int length, const ip_address *addr) { u_char buffer[SHA1_DIGEST_SIZE]; SHA1_CTX ctx; do { if (initiator) { get_rnd_bytes(cookie, length); } else /* Responder cookie */ { /* This looks as good as any way */ size_t addr_length; static u_int32_t counter = 0; unsigned char addr_buff[ sizeof(union {struct in_addr; struct in6_addr;})]; addr_length = addrbytesof(addr, addr_buff, sizeof(addr_buff)); SHA1Init(&ctx); SHA1Update(&ctx, addr_buff, addr_length); SHA1Update(&ctx, secret_of_the_day, sizeof(secret_of_the_day)); counter++; SHA1Update(&ctx, (const void *) &counter, sizeof(counter)); SHA1Final(buffer, &ctx); memcpy(cookie, buffer, length); } } while (is_zero_cookie(cookie)); /* probably never loops */ }
/* Generate a cookie. * First argument is true if we're to create an Initiator cookie. * Length SHOULD be a multiple of sizeof(u_int32_t). */ void get_cookie(bool initiator, u_int8_t *cookie, int length, ip_address *addr) { hasher_t *hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1); u_char buffer[HASH_SIZE_SHA1]; do { if (initiator) { rng_t *rng; rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG); rng->get_bytes(rng, length, cookie); rng->destroy(rng); } else /* Responder cookie */ { chunk_t addr_chunk, secret_chunk, counter_chunk; size_t addr_len; static u_int32_t counter = 0; unsigned char addr_buf[ sizeof(union {struct in_addr A; struct in6_addr B;})]; addr_len = addrbytesof(addr, addr_buf, sizeof(addr_buf)); addr_chunk = chunk_create(addr_buf, addr_len); secret_chunk = chunk_create(secret_of_the_day, HASH_SIZE_SHA1); counter++; counter_chunk = chunk_create((void *) &counter, sizeof(counter)); hasher->get_hash(hasher, addr_chunk, NULL); hasher->get_hash(hasher, secret_chunk, NULL); hasher->get_hash(hasher, counter_chunk, buffer); memcpy(cookie, buffer, length); } } while (is_zero_cookie(cookie)); /* probably never loops */ hasher->destroy(hasher); }