示例#1
0
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;
}
示例#2
0
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;
}
示例#3
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;
}
示例#4
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;
}
示例#5
0
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;
}