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_instantiate_algorithm(struct ccdrbg_state *drbg, unsigned long entropyLength, const void *entropy, unsigned long nonceLength, const void *nonce, unsigned long psLength, const void *ps) { // TODO: The NIST code passes nonce (i.e. HMAC key) to generate, but cc interface isn't set up that way struct ccdrbg_nisthmac_state *state=(struct ccdrbg_nisthmac_state *)drbg; // 1. seed_material = entropy_input || nonce || personalization_string. // 2. Set Key to outlen bits of zeros. cc_zero(state->keysize, state->key); // 3. Set V to outlen/8 bytes of 0x01. CC_MEMSET(state->v, 0x01, state->vsize); // 4. (Key, V) = HMAC_DRBG_Update (seed_material, Key, V). hmac_dbrg_update(drbg, entropyLength, entropy, nonceLength, nonce, psLength, ps); // 5. reseed_counter = 1. state->reseed_counter = 1; return 0; }
static int generate(struct ccdrbg_state *drbg, unsigned long numBytes, void *outBytes, unsigned long inputLen, const void *input) { struct ccdrbg_nisthmac_state *state = (struct ccdrbg_nisthmac_state *)drbg; const struct ccdrbg_nisthmac_custom *custom = state->info->custom; const struct ccdigest_info *di = custom->di; if (numBytes > NH_MAX_BYTES_PER_REQUEST) return hmac_dbrg_error(CCDRBG_STATUS_PARAM_ERROR, "Requested too many bytes in one request"); // 1. If (reseed_counter > 2^^48), then Return (“Reseed required”, Null, V, Key, reseed_counter). if (state->reseed_counter > NH_RESEED_INTERVAL) return hmac_dbrg_error(CCDRBG_STATUS_NEED_RESEED, "Reseed required"); // 2. If additional_input ≠ Null, then (Key, V) = HMAC_DRBG_Update (additional_input, Key, V). if (input && inputLen) hmac_dbrg_update(drbg, inputLen, input, 0, NULL, 0, NULL); // hmac_dbrg_generate_algorithm char *outPtr = (char *) outBytes; while (numBytes > 0) { if (!state->bytesLeft) { // 5. V=HMAC(K,V). cchmac(di, state->keysize, state->key, state->vsize, state->v, state->v); state->bytesLeft = di->output_size;//di->output_size; state->vsize } size_t outLength = numBytes > state->bytesLeft ? state->bytesLeft : numBytes; memcpy(outPtr, state->v, outLength); state->bytesLeft -= outLength; outPtr += outLength; numBytes -= outLength; } // 6. (Key, V) = HMAC_DRBG_Update (additional_input, Key, V). hmac_dbrg_update(drbg, inputLen, input, 0, NULL, 0, NULL); // 7. reseed_counter = reseed_counter + 1. state->reseed_counter++; #ifdef DEBUGFOO dumpState("generate: ", state); #endif return 0; }
static int reseed(struct ccdrbg_state *drbg, unsigned long entropyLength, const void *entropy, unsigned long inputlen, const void *input) { struct ccdrbg_nisthmac_state *state=(struct ccdrbg_nisthmac_state *)drbg; int rx = hmac_dbrg_update(drbg, entropyLength, entropy, inputlen, input, 0, NULL); state->reseed_counter = 1; #ifdef DEBUGFOO dumpState("Reseed: ", state); #endif return rx; }
static int reseed(struct ccdrbg_state *drbg, size_t entropyLength, const void *entropy, size_t additionalLength, const void *additional) { struct ccdrbg_nisthmac_state *state = (struct ccdrbg_nisthmac_state *)drbg; int rc = validate_inputs(state, entropyLength, additionalLength, 0); if(rc!=CCDRBG_STATUS_OK) return rc; int rx = hmac_dbrg_update(drbg, entropyLength, entropy, additionalLength, additional, 0, NULL); state->reseed_counter = 1; #if DRBG_NISTHMAC_DEBUG dumpState("Reseed: ", state); #endif return rx; }