static void ctr_Update(DRBG_CTX *dctx, const unsigned char *in1, size_t in1len, const unsigned char *in2, size_t in2len, const unsigned char *nonce, size_t noncelen) { DRBG_CTR_CTX *cctx = &dctx->d.ctr; /* ks is already setup for correct key */ inc_128(cctx); AES_encrypt(cctx->V, cctx->K, &cctx->ks); /* If keylen longer than 128 bits need extra encrypt */ if (cctx->keylen != 16) { inc_128(cctx); AES_encrypt(cctx->V, cctx->K + 16, &cctx->ks); } inc_128(cctx); AES_encrypt(cctx->V, cctx->V, &cctx->ks); /* If 192 bit key part of V is on end of K */ if (cctx->keylen == 24) { memcpy(cctx->V + 8, cctx->V, 8); memcpy(cctx->V, cctx->K + 24, 8); } if (dctx->flags & DRBG_FLAG_CTR_USE_DF) { /* If no input reuse existing derived value */ if (in1 || nonce || in2) ctr_df(cctx, in1, in1len, nonce, noncelen, in2, in2len); /* If this a reuse input in1len != 0 */ if (in1len) ctr_XOR(cctx, cctx->KX, dctx->seedlen); } else { ctr_XOR(cctx, in1, in1len); ctr_XOR(cctx, in2, in2len); } AES_set_encrypt_key(cctx->K, dctx->strength, &cctx->ks); #if 0 fprintf(stderr, "K+V after update is:\n"); BIO_dump_fp(stderr, cctx->K, cctx->keylen); BIO_dump_fp(stderr, cctx->V, 16); #endif }
/* * NB the no-df Update in SP800-90A specifies a constant input length * of seedlen, however other uses of this algorithm pad the input with * zeroes if necessary and have up to two parameters XORed together, * so we handle both cases in this function instead. */ static void ctr_update(RAND_DRBG *drbg, const unsigned char *in1, size_t in1len, const unsigned char *in2, size_t in2len, const unsigned char *nonce, size_t noncelen) { RAND_DRBG_CTR *ctr = &drbg->ctr; /* ks is already setup for correct key */ inc_128(ctr); AES_encrypt(ctr->V, ctr->K, &ctr->ks); /* If keylen longer than 128 bits need extra encrypt */ if (ctr->keylen != 16) { inc_128(ctr); AES_encrypt(ctr->V, ctr->K + 16, &ctr->ks); } inc_128(ctr); AES_encrypt(ctr->V, ctr->V, &ctr->ks); /* If 192 bit key part of V is on end of K */ if (ctr->keylen == 24) { memcpy(ctr->V + 8, ctr->V, 8); memcpy(ctr->V, ctr->K + 24, 8); } if (drbg->flags & RAND_DRBG_FLAG_CTR_USE_DF) { /* If no input reuse existing derived value */ if (in1 != NULL || nonce != NULL || in2 != NULL) ctr_df(ctr, in1, in1len, nonce, noncelen, in2, in2len); /* If this a reuse input in1len != 0 */ if (in1len) ctr_XOR(ctr, ctr->KX, drbg->seedlen); } else { ctr_XOR(ctr, in1, in1len); ctr_XOR(ctr, in2, in2len); } AES_set_encrypt_key(ctr->K, drbg->strength, &ctr->ks); }