static int generate_block(struct ccdrbg_nistctr_state * drbg, uint32_t *blk) { int rc; uint8_t temp2[CCADRBG_BLOCKSIZE(drbg)]; // the folowing lines are performed as rquested in Radar 19129408 if (drbg->strictFIPS) { rc = gen_block(drbg, temp2); cc_require(rc==CCDRBG_STATUS_OK, errOut); rc = gen_block(drbg, blk); cc_require(rc==CCDRBG_STATUS_OK, errOut); rc = cc_cmp_safe(CCADRBG_BLOCKSIZE(drbg), blk, temp2); rc = (rc==0) ? CCDRBG_STATUS_ABORT: CCDRBG_STATUS_OK; errOut: cc_clear(CCADRBG_BLOCKSIZE(drbg), temp2); }else{ rc=gen_block(drbg, blk); } if(rc==CCDRBG_STATUS_ABORT){ //The world as we know it has come to an end //the DRBG data structure is zeroized. subsequent calls to //DRBG ends up in NULL dereferencing and/or unpredictable state. //catastrophic error in SP 800-90A done((struct ccdrbg_state *)drbg); cc_abort(NULL); } return rc; }
static int generate(struct ccdrbg_state *drbg, size_t dataOutLength, void *dataOut, size_t additionalLength, const void *additional) { struct ccdrbg_nisthmac_state *state = (struct ccdrbg_nisthmac_state *)drbg; const struct ccdrbg_nisthmac_custom *custom = state->custom; const struct ccdigest_info *di = custom->di; int rc = validate_gen_params(state->reseed_counter, dataOutLength, additional==NULL?0:additionalLength); if(rc!=CCDRBG_STATUS_OK) return rc; // 2. If additional_input ≠ Null, then (Key, V) = HMAC_DRBG_Update (additional_input, Key, V). if (additional && additionalLength) hmac_dbrg_update(drbg, additionalLength, additional, 0, NULL, 0, NULL); // hmac_dbrg_generate_algorithm char *outPtr = (char *) dataOut; while (dataOutLength > 0) { if (!state->bytesLeft) { // 5. V=HMAC(K,V). cchmac(di, state->keysize, state->key, state->vsize, state->nextvptr, state->vptr); // Won't be returned // FIPS 140-2 4.9.2 Conditional Tests // "Each subsequent generation of an n-bit block shall be compared with the previously generated block. The test shall fail if any two compared n-bit blocks are equal." if (0==cc_cmp_safe(state->vsize, state->vptr, state->nextvptr)) { //The world as we know it has come to an end //the DRBG data structure is zeroized. subsequent calls to //DRBG ends up in NULL dereferencing and/or unpredictable state. //catastrophic error in SP 800-90A done(drbg); rc=CCDRBG_STATUS_ABORT; cc_abort(NULL); goto errOut; } CC_SWAP(state->nextvptr, state->vptr); state->bytesLeft = state->vsize; #if DRBG_NISTHMAC_DEBUG cc_print("generate blk: ", state->vsize, state->vptr); #endif } size_t outLength = dataOutLength > state->bytesLeft ? state->bytesLeft : dataOutLength; CC_MEMCPY(outPtr, state->vptr, outLength); state->bytesLeft -= outLength; outPtr += outLength; dataOutLength -= outLength; } // 6. (Key, V) = HMAC_DRBG_Update (additional_input, Key, V). hmac_dbrg_update(drbg, additionalLength, additional, 0, NULL, 0, NULL); // 7. reseed_counter = reseed_counter + 1. state->reseed_counter++; #if DRBG_NISTHMAC_DEBUG dumpState("generate end: ", state); cc_print("generate end nxt: ", state->vsize, state->nextvptr); #endif rc=CCDRBG_STATUS_OK; errOut: return rc; }
static int hmac_dbrg_update(struct ccdrbg_state *drbg, size_t daLen, const void *da, size_t dbLen, const void *db, size_t dcLen, const void *dc ) { int rc=CCDRBG_STATUS_ERROR; struct ccdrbg_nisthmac_state *state = (struct ccdrbg_nisthmac_state *)drbg; const struct ccdigest_info *di = state->custom->di; const unsigned char cZero = 0x00; const unsigned char cOne = 0x01; cchmac_ctx_decl(di->state_size, di->block_size, ctx); cchmac_init(di, ctx, state->keysize, state->key); // 1. K = HMAC (K, V || 0x00 || provided_data). cchmac_update(di, ctx, state->vsize, state->vptr); cchmac_update(di, ctx, 1, &cZero); if (da && daLen) cchmac_update(di, ctx, daLen, da); if (db && dbLen) cchmac_update(di, ctx, dbLen, db); if (dc && dcLen) cchmac_update(di, ctx, dcLen, dc); cchmac_final(di, ctx, state->key); // One parameter must be non-empty, or return if (((da && daLen) || (db && dbLen) || (dc && dcLen))) { // 2. V=HMAC(K,V). cchmac(di, state->keysize, state->key, state->vsize, state->vptr, state->vptr); // 4. K = HMAC (K, V || 0x01 || provided_data). cchmac_init(di, ctx, state->keysize, state->key); cchmac_update(di, ctx, state->vsize, state->vptr); cchmac_update(di, ctx, 1, &cOne); if (da && daLen) cchmac_update(di, ctx, daLen, da); if (db && dbLen) cchmac_update(di, ctx, dbLen, db); if (dc && dcLen) cchmac_update(di, ctx, dcLen, dc); cchmac_final(di, ctx, state->key); } // If additional data 5. V=HMAC(K,V) // If no addtional data, this is step 2. V=HMAC(K,V). state->bytesLeft = 0; // FIPS 140-2 4.9.2 Conditional Tests // "the first n-bit block generated after power-up, initialization, or reset shall not be used, but shall be saved for comparison with the next n-bit block to be generated" // Generate the first block and the second block. Compare for FIPS and discard the first block // We keep the second block as the first set of data to be returned cchmac(di, state->keysize, state->key, state->vsize, state->vptr, state->vptr); // First block cchmac(di, state->keysize, state->key, state->vsize, state->vptr, state->nextvptr); // First to be returned if (0==cc_cmp_safe(state->vsize, state->vptr, state->nextvptr)) { //The world as we know it has come to an end //the DRBG data structure is zeroized. subsequent calls to //DRBG ends up in NULL dereferencing and/or unpredictable state. //catastrophic error in SP 800-90A done(drbg); rc=CCDRBG_STATUS_ABORT; cc_abort(NULL); goto errOut; } rc=CCDRBG_STATUS_OK; errOut: return rc; }