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); }