krb5_error_code krb5int_derive_key(const struct krb5_enc_provider *enc, krb5_key inkey, krb5_key *outkey, const krb5_data *in_constant) { krb5_keyblock keyblock; krb5_error_code ret; krb5_key dkey; *outkey = NULL; /* Check for a cached result. */ dkey = find_cached_dkey(inkey->derived, in_constant); if (dkey != NULL) { *outkey = dkey; return 0; } /* Derive into a temporary keyblock. */ keyblock.length = enc->keylength; keyblock.contents = malloc(keyblock.length); /* Set the enctype as the krb5_k_free_key will iterate over list or derived keys and invoke krb5_k_free_key which will lookup the enctype for key_cleanup handler */ keyblock.enctype = inkey->keyblock.enctype; if (keyblock.contents == NULL) return ENOMEM; ret = krb5int_derive_keyblock(enc, inkey, &keyblock, in_constant); if (ret) goto cleanup; /* Cache the derived key. */ ret = add_cached_dkey(inkey, in_constant, &keyblock, &dkey); if (ret != 0) goto cleanup; *outkey = dkey; cleanup: zapfree(keyblock.contents, keyblock.length); return ret; }
krb5_error_code krb5int_derive_key(const struct krb5_enc_provider *enc, krb5_key inkey, krb5_key *outkey, const krb5_data *in_constant, enum deriv_alg alg) { krb5_keyblock keyblock; krb5_error_code ret; krb5_key dkey; *outkey = NULL; /* Check for a cached result. */ dkey = find_cached_dkey(inkey->derived, in_constant); if (dkey != NULL) { *outkey = dkey; return 0; } /* Derive into a temporary keyblock. */ keyblock.length = enc->keylength; keyblock.contents = malloc(keyblock.length); keyblock.enctype = inkey->keyblock.enctype; if (keyblock.contents == NULL) return ENOMEM; ret = krb5int_derive_keyblock(enc, inkey, &keyblock, in_constant, alg); if (ret) goto cleanup; /* Cache the derived key. */ ret = add_cached_dkey(inkey, in_constant, &keyblock, &dkey); if (ret != 0) goto cleanup; *outkey = dkey; cleanup: zapfree(keyblock.contents, keyblock.length); return ret; }