Exemple #1
0
static int ECDSA_POST()
{
	// Pair wise consistency test
	size_t keySize = 256; 
	int iResult = 0;

	struct ccrng_system_state system_rng;
	struct ccrng_state *rng = (struct ccrng_state *)&system_rng;
    ccrng_system_init(&system_rng);
	
	ccec_const_cp_t cp = ccec_get_cp(keySize);
	ccec_full_ctx_decl_cp(cp, full_ec_key);
    size_t signedDataLen = ccec_sign_max_size(cp);
    uint8_t signedData[signedDataLen];
    cc_zero(signedDataLen, signedData);
	
    iResult = ccec_generate_key_fips(cp, rng, full_ec_key);
	ccec_full_ctx_clear_cp(cp, full_ec_key);
    ccrng_system_done(&system_rng);
	return iResult;
}
int
ccecies_encrypt_gcm_composite(ccec_pub_ctx_t public_key,
                    const ccecies_gcm_t ecies,
                    uint8_t *exported_public_key, /* output - length from ccecies_pub_key_size */
                    uint8_t *ciphertext,          /* output - length same as plaintext_len */
                    uint8_t *mac_tag,             /* output - length ecies->mac_length */
                    size_t plaintext_len,   const uint8_t *plaintext,
                    size_t sharedinfo1_byte_len, const void *sharedinfo_1,
                    size_t sharedinfo2_byte_len, const void *sharedinfo_2
)
{
    int status=-1;

    // Contexts:
    ccec_full_ctx_decl_cp(ccec_ctx_cp(public_key), ephemeral_key);
    size_t   skey_size = ccec_cp_prime_size(ccec_ctx_cp(public_key));
    uint8_t  skey[skey_size];
    const struct ccmode_gcm *gcm_encrypt=ecies->gcm;
    ccgcm_ctx_decl(gcm_encrypt->size,gcm_ctx);
    size_t exported_public_key_size;

    // 1) Generate ephemeral EC key pair
    cc_assert(ecies->rng!=NULL);
    cc_require(ccecdh_generate_key(ccec_ctx_cp(public_key), ecies->rng, ephemeral_key)==0,errOut);

#if CC_DEBUG_ECIES
    ccec_print_full_key("Ephemeral key",ephemeral_key);
#endif

    // 2) ECDH with input public key
    cc_require(ccecdh_compute_shared_secret(ephemeral_key, public_key, &skey_size, skey,ecies->rng)==0,errOut);

#if CC_DEBUG_ECIES
    cc_print("Shared secret key",skey_size,skey);
#endif

    // 3) Export ephemeral public key
    cc_require( ccecies_export(0, ecies->options, exported_public_key, ephemeral_key)==0, errOut);

    // 4) Derive Enc / Mac key
    // Hash(skey|00000001|sharedinfo_1)
    cc_assert(ecies->key_length<=skey_size);
    exported_public_key_size=ccecies_pub_key_size(ephemeral_key,ecies);
    if (ECIES_EPH_PUBKEY_IN_SHAREDINFO1 == (ecies->options & ECIES_EPH_PUBKEY_IN_SHAREDINFO1))
    {   // use ephemeral public key as shared info 1
        cc_require(ccansikdf_x963(ecies->di,
                                  skey_size,skey,
                                  exported_public_key_size,exported_public_key,
                                  ecies->key_length,skey)==0,errOut);
    }
    else
    {
        cc_require(ccansikdf_x963(ecies->di,
                                  skey_size,skey,
                                  sharedinfo1_byte_len,sharedinfo_1,
                                  ecies->key_length,skey)==0,errOut);
    }

#if CC_DEBUG_ECIES
    cc_print("Cipher key",ecies->key_length,skey);
#endif

    // 5) Encrypt
    ccgcm_init(gcm_encrypt, gcm_ctx,ecies->key_length,skey);
    ccgcm_set_iv(gcm_encrypt,gcm_ctx,sizeof(ecies_iv_data),ecies_iv_data);
    if ((sharedinfo_2!=NULL) && (sharedinfo2_byte_len>0)) {
        ccgcm_gmac(gcm_encrypt,gcm_ctx,sharedinfo2_byte_len,sharedinfo_2);
    }
    else
    {
        ccgcm_gmac(gcm_encrypt,gcm_ctx,0,NULL);
    }
    ccgcm_update(gcm_encrypt,gcm_ctx,
                 plaintext_len,plaintext,
                 ciphertext);

#if CC_DEBUG_ECIES
    cc_print("Encrypted message",plaintext_len,ciphertext);
#endif

    // 6) Mac (with SharedInfo 2)
    // sec1, p51: recommended: SharedInfo2 ended in a counter giving its length.
    ccgcm_finalize(gcm_encrypt,gcm_ctx,ecies->mac_length,mac_tag);
#if CC_DEBUG_ECIES
    cc_print("Mac Tag",ecies->mac_length,mac_tag);
#endif

    // Success
    status=0;

errOut:
    // Clear key material info
    ccgcm_ctx_clear(gcm_encrypt->size,gcm_ctx);
    cc_clear(sizeof(skey),skey);
    ccec_full_ctx_clear_cp(ccec_ctx_cp(public_key), ephemeral_key);
    return status;
}
SecKeyRef SOSUserKeygen(CFDataRef password, CFDataRef parameters, CFErrorRef *error)
{
    size_t saltlen;
    const uint8_t *salt = NULL;

    size_t iterations = 0;
    size_t keysize = 0;

    const uint8_t *der = CFDataGetBytePtr(parameters);
    const uint8_t *der_end = der + CFDataGetLength(parameters);

    der = der_decode_pbkdf2_params(&saltlen, &salt, &iterations, &keysize, der, der_end);

    if (der == NULL) {
        SOSCreateErrorWithFormat(kSOSErrorDecodeFailure, NULL, error, NULL,
                                 CFSTR("Bad paramter encoding, got: %@"), parameters);
        return NULL;
    }
    if (keysize != 256) {
        SOSCreateErrorWithFormat(kSOSErrorUnsupported, NULL, error, NULL,
                                 CFSTR("Key size not supported, requested %zd."), keysize);
        return NULL;
    }
    if (saltlen < 4) {
        SOSCreateErrorWithFormat(kSOSErrorUnsupported, NULL, error, NULL,
                                 CFSTR("Salt length not supported, requested %zd."), saltlen);
        return NULL;
    }
    if (iterations < ITERATIONMIN) {
        SOSCreateErrorWithFormat(kSOSErrorUnsupported, NULL, error, NULL,
                                 CFSTR("Too few iterations, params suggested %zd."), iterations);
        return NULL;
    }

    const uint8_t *password_bytes = CFDataGetBytePtr(password);
    size_t password_length = CFDataGetLength(password);

    const size_t maxbytes = 128;

    ccec_const_cp_t cp = ccec_get_cp(keysize);
    struct ccrng_pbkdf2_prng_state pbkdf2_prng;

    ccec_full_ctx_decl_cp(cp, tmpkey);

    secnotice("keygen", "Generating key for: iterations %zd, keysize %zd: %@", iterations, keysize, parameters);

    if (ccrng_pbkdf2_prng_init(&pbkdf2_prng, maxbytes,
                                password_length, password_bytes,
                                saltlen, salt,
                                iterations)) {
        SOSCreateError(kSOSErrorProcessingFailure, CFSTR("prng init failed"), NULL, error);
        return NULL;
    }

    if (ccec_generate_key(cp, (struct ccrng_state *)&pbkdf2_prng, tmpkey)) {
        SOSCreateError(kSOSErrorProcessingFailure, CFSTR("Keygen failed"), NULL, error);
        return NULL;
    }


    return ccec2SecKey(tmpkey);
}