/* Initializes the nonce level random generator. * * the @new_key must be provided. * * @init must be non zero on first initialization, and * zero on any subsequent reinitializations. */ static int single_prng_init(struct prng_ctx_st *ctx, uint8_t new_key[PRNG_KEY_SIZE], unsigned new_key_size, unsigned init) { uint8_t nonce[CHACHA_NONCE_SIZE]; memset(nonce, 0, sizeof(nonce)); /* to prevent valgrind from whinning */ if (init == 0) { /* use the previous key to generate IV as well */ chacha_crypt(&ctx->ctx, sizeof(nonce), nonce, nonce); /* Add key continuity by XORing the new key with data generated * from the old key */ chacha_crypt(&ctx->ctx, new_key_size, new_key, new_key); } else { struct timespec now; /* current time */ ctx->forkid = _gnutls_get_forkid(); gettime(&now); memcpy(nonce, &now, MIN(sizeof(nonce), sizeof(now))); ctx->last_reseed = now.tv_sec; } chacha_set_key(&ctx->ctx, new_key); chacha_set_nonce(&ctx->ctx, nonce); zeroize_key(new_key, new_key_size); ctx->counter = 0; return 0; }
void chacha_poly1305_set_nonce (struct chacha_poly1305_ctx *ctx, const uint8_t *nonce) { union { uint32_t x[_CHACHA_STATE_LENGTH]; uint8_t subkey[32]; } u; chacha_set_nonce (&ctx->chacha, nonce); /* Generate authentication key */ _chacha_core (u.x, ctx->chacha.state, CHACHA_ROUNDS); poly1305_set_key (&ctx->poly1305, u.subkey); /* For final poly1305 processing */ memcpy (ctx->s.b, u.subkey + 16, 16); /* Increment block count */ ctx->chacha.state[12] = 1; ctx->auth_size = ctx->data_size = ctx->index = 0; }