* @retval #YACA_ERROR_OUT_OF_MEMORY Out of memory error
* @retval #YACA_ERROR_INTERNAL Internal error
*
+ * @see yaca_key_derive_kdf()
* @see yaca_simple_calculate_digest()
* @see yaca_free()
*/
char **secret,
size_t *secret_len);
+/**
+ * @brief Derives a key material from shared secret.
+ *
+ * @since_tizen 3.0
+ *
+ * @remarks The @a info parameter is ANSI X9.42 OtherInfo or ANSI X9.62 SharedInfo structure,
+ * more information can be found in ANSI X9.42/62 standard specification
+ *
+ * @remarks The @a key_material or separate parts of it can be used to import a symmetric key with yaca_key_import()
+ *
+ * @remarks The @a key_material should be freed using yaca_free()
+ *
+ * @param[in] kdf Key derivation function
+ * @param[in] algo Digest algorithm that should be used in key derivation
+ * @param[in] secret Shared secret
+ * @param[in] secret_len Size of the shared secret
+ * @param[in] info Optional additional info, use NULL if not appending extra info
+ * @param[in] info_len Length of additional info, use 0 if not using additional info
+ * @param[in] key_material_bit_len Length of a key material (in bits) to be generated
+ * @param[out] key_material Newly generated key material
+ *
+ * @return #YACA_ERROR_NONE on success, negative on error
+ * @retval #YACA_ERROR_NONE Successful
+ * @retval #YACA_ERROR_INVALID_PARAMETER Required parameters have incorrect values (NULL, 0,
+ * invalid algo or kdf)
+ * @retval #YACA_ERROR_OUT_OF_MEMORY Out of memory error
+ * @retval #YACA_ERROR_INTERNAL Internal error
+ *
+ * @see #yaca_kdf_e
+ * @see #yaca_digest_algorithm_e
+ * @see yaca_key_derive_dh()
+ * @see yaca_key_import()
+ * @see yaca_free()
+ */
+int yaca_key_derive_kdf(yaca_kdf_e kdf,
+ yaca_digest_algorithm_e algo,
+ const char *secret,
+ size_t secret_len,
+ const char *info,
+ size_t info_len,
+ size_t key_material_bit_len,
+ char **key_material);
+
/**
* @brief Derives a key from user password (PKCS #5 a.k.a. pbkdf2 algorithm).
*
int ret;
char *secret = NULL;
size_t secret_len;
+ char *key_material = NULL;
yaca_key_h private_key = YACA_KEY_NULL;
yaca_key_h public_key = YACA_KEY_NULL;
yaca_key_h params = YACA_KEY_NULL;
+ yaca_key_h aes_key = YACA_KEY_NULL;
ret = yaca_key_extract_parameters(pkey, ¶ms);
if (ret != YACA_ERROR_NONE)
if (ret != YACA_ERROR_NONE)
goto exit;
+ ret = yaca_key_derive_kdf(YACA_KDF_X962, YACA_DIGEST_SHA512, secret, secret_len,
+ NULL, 0, YACA_KEY_LENGTH_192BIT, &key_material);
+ if (ret != YACA_ERROR_NONE)
+ goto exit;
+
+ ret = yaca_key_import(YACA_KEY_TYPE_SYMMETRIC, NULL, key_material, YACA_KEY_LENGTH_192BIT,
+ &aes_key);
+ if (ret != YACA_ERROR_NONE)
+ goto exit;
+
dump_hex(secret, secret_len, "\n***** Peer Secret: *****");
+ dump_hex(key_material, YACA_KEY_LENGTH_192BIT, "\n***** Peer AES key: *****");
exit:
yaca_key_destroy(private_key);
yaca_key_destroy(params);
+ yaca_key_destroy(aes_key);
yaca_free(secret);
+ yaca_free(key_material);
return public_key;
}
int ret;
char *secret = NULL;
size_t secret_len;
+ char *key_material = NULL;
yaca_key_h private_key = YACA_KEY_NULL;
yaca_key_h public_key = YACA_KEY_NULL;
yaca_key_h peer_key = YACA_KEY_NULL;
+ yaca_key_h aes_key = YACA_KEY_NULL;
printf("\n***** Diffie Hellman key exchange with standard DH parameters *****");
if (ret != YACA_ERROR_NONE)
goto exit;
+ ret = yaca_key_derive_kdf(YACA_KDF_X962, YACA_DIGEST_SHA512, secret, secret_len,
+ NULL, 0, YACA_KEY_LENGTH_192BIT, &key_material);
+ if (ret != YACA_ERROR_NONE)
+ goto exit;
+
+ ret = yaca_key_import(YACA_KEY_TYPE_SYMMETRIC, NULL, key_material, YACA_KEY_LENGTH_192BIT,
+ &aes_key);
+ if (ret != YACA_ERROR_NONE)
+ goto exit;
+
dump_hex(secret, secret_len, "\n***** My Secret: *****");
+ dump_hex(key_material, YACA_KEY_LENGTH_192BIT, "\n***** My AES key: *****");
exit:
yaca_key_destroy(private_key);
yaca_key_destroy(public_key);
yaca_key_destroy(peer_key);
+ yaca_key_destroy(aes_key);
yaca_free(secret);
+ yaca_free(key_material);
}
void key_exchange_dh_generated_parameters(void)
int ret;
char *secret = NULL;
size_t secret_len;
+ char *key_material = NULL;
yaca_key_h params = YACA_KEY_NULL;
yaca_key_h private_key = YACA_KEY_NULL;
yaca_key_h public_key = YACA_KEY_NULL;
yaca_key_h peer_key = YACA_KEY_NULL;
+ yaca_key_h aes_key = YACA_KEY_NULL;
printf("\n***** Diffie Hellman key exchange with parameters generation *****");
if (ret != YACA_ERROR_NONE)
goto exit;
+ ret = yaca_key_derive_kdf(YACA_KDF_X962, YACA_DIGEST_SHA512, secret, secret_len,
+ NULL, 0, YACA_KEY_LENGTH_192BIT, &key_material);
+ if (ret != YACA_ERROR_NONE)
+ goto exit;
+
+ ret = yaca_key_import(YACA_KEY_TYPE_SYMMETRIC, NULL, key_material, YACA_KEY_LENGTH_192BIT,
+ &aes_key);
+ if (ret != YACA_ERROR_NONE)
+ goto exit;
+
dump_hex(secret, secret_len, "\n***** My Secret: *****");
+ dump_hex(key_material, YACA_KEY_LENGTH_192BIT, "\n***** My AES key: *****");
exit:
yaca_key_destroy(params);
yaca_key_destroy(private_key);
yaca_key_destroy(public_key);
yaca_key_destroy(peer_key);
+ yaca_key_destroy(aes_key);
yaca_free(secret);
+ yaca_free(key_material);
}
void key_exchange_ecdh(void)
int ret;
char *secret = NULL;
size_t secret_len;
+ char *key_material = NULL;
yaca_key_h private_key = YACA_KEY_NULL;
yaca_key_h public_key = YACA_KEY_NULL;
yaca_key_h peer_key = YACA_KEY_NULL;
+ yaca_key_h aes_key = YACA_KEY_NULL;
printf("\n***** Elliptic Curve Diffie Hellman key exchange *****");
if (ret != YACA_ERROR_NONE)
goto exit;
+ ret = yaca_key_derive_kdf(YACA_KDF_X962, YACA_DIGEST_SHA512, secret, secret_len,
+ NULL, 0, YACA_KEY_LENGTH_192BIT, &key_material);
+ if (ret != YACA_ERROR_NONE)
+ goto exit;
+
+ ret = yaca_key_import(YACA_KEY_TYPE_SYMMETRIC, NULL, key_material, YACA_KEY_LENGTH_192BIT,
+ &aes_key);
+ if (ret != YACA_ERROR_NONE)
+ goto exit;
+
dump_hex(secret, secret_len, "\n***** My Secret: *****");
+ dump_hex(key_material, YACA_KEY_LENGTH_192BIT, "\n***** My AES key: *****");
exit:
yaca_key_destroy(private_key);
yaca_key_destroy(public_key);
yaca_key_destroy(peer_key);
+ yaca_key_destroy(aes_key);
yaca_free(secret);
+ yaca_free(key_material);
}
int main()
return ret;
}
+API int yaca_key_derive_kdf(yaca_kdf_e kdf,
+ yaca_digest_algorithm_e algo,
+ const char *secret,
+ size_t secret_len,
+ const char *info,
+ size_t info_len,
+ size_t key_material_bit_len,
+ char **key_material)
+{
+ int ret;
+ char *out = NULL;
+ const EVP_MD *md;
+
+ if (secret == NULL || secret_len == 0 ||
+ (info == NULL && info_len > 0) || (info != NULL && info_len == 0) ||
+ key_material_bit_len == 0 || key_material == NULL)
+ return YACA_ERROR_INVALID_PARAMETER;
+
+ ret = yaca_zalloc(key_material_bit_len, (void**)&out);
+ if (ret != YACA_ERROR_NONE)
+ return ret;
+
+ ret = digest_get_algorithm(algo, &md);
+ if (ret != YACA_ERROR_NONE)
+ goto exit;
+
+ switch (kdf) {
+ case YACA_KDF_X942:
+ ret = DH_KDF_X9_42((unsigned char*)out, key_material_bit_len,
+ (unsigned char*)secret, secret_len,
+ OBJ_nid2obj(NID_id_smime_alg_ESDH), (unsigned char*)info, info_len, md);
+ if (ret != 1 || out == NULL) {
+ ret = YACA_ERROR_INTERNAL;
+ ERROR_DUMP(ret);
+ goto exit;
+ }
+ break;
+ case YACA_KDF_X962:
+ ret = ECDH_KDF_X9_62((unsigned char*)out, key_material_bit_len,
+ (unsigned char*)secret, secret_len,
+ (unsigned char*)info, info_len, md);
+ if (ret != 1 || out == NULL) {
+ ret = YACA_ERROR_INTERNAL;
+ ERROR_DUMP(ret);
+ goto exit;
+ }
+ break;
+ default:
+ ret = YACA_ERROR_INVALID_PARAMETER;
+ goto exit;
+ }
+
+ *key_material = out;
+ out = NULL;
+ ret = YACA_ERROR_NONE;
+
+exit:
+ yaca_free(out);
+ return ret;
+}
+
API int yaca_key_derive_pbkdf2(const char *password,
const char *salt,
size_t salt_len,