* @return #YACA_ERROR_NONE on success, negative on error
* @retval #YACA_ERROR_NONE Successful
* @retval #YACA_ERROR_INVALID_PARAMETER Either of the params is NULL
+ *
+ * @see #yaca_key_type_e
*/
int yaca_key_get_type(const yaca_key_h key, yaca_key_type_e *key_type);
*
* @since_tizen 3.0
*
+ * @remarks For elliptic curves @a key_bit_len returns values from #yaca_key_bit_length_ec_e
+ *
* @param[in] key Key which length we return
* @param[out] key_bit_len Key length in bits
*
* @retval #YACA_ERROR_NONE Successful
* @retval #YACA_ERROR_INVALID_PARAMETER Either of the params is NULL
* @retval #YACA_ERROR_INTERNAL Internal error
+ *
+ * @see #yaca_key_bit_length_e
+ * @see #yaca_key_bit_length_ec_e
*/
int yaca_key_get_bit_length(const yaca_key_h key, size_t *key_bit_len);
* @remarks Supported key lengths:
* - RSA: length >= 256bits
* - DSA: length >= 512bits, multiple of 64
+ * - EC: @a key_bit_len takes values from #yaca_key_bit_length_ec_e
*
* @remarks The @a key should be released using yaca_key_destroy()
*
*
* @see #yaca_key_type_e
* @see #yaca_key_bit_length_e
+ * @see #yaca_key_bit_length_ec_e
* @see yaca_key_destroy()
*/
int yaca_key_generate(yaca_key_type_e key_type,
* @{
*/
+/* The format of the unsigned int used to indicate key_bit_len is as follows:
+ *
+ * Bits indicating a type:
+ * bits 31-30 (2 bits) indicate key_length type:
+ * 00(0) - regular type for RSA, DSA and DH
+ * 01(1) - elliptic curve
+ * remaining combinations reserved
+ *
+ * Bits for a regular type:
+ * bits 29-0 (30 bits) indicate length of the key in bits
+ *
+ * Bits for an elliptic curve type:
+ * bits 29-26 (4 bits) indicate type of an elliptic curve:
+ * 0000(0) - X9.62 Prime
+ * 0001(1) - SECP
+ * 0010(2) - SECT
+ * 0011(3) - Brainpool
+ * remaining combinations reserved (c2pnb, c2tnb, c2onb...)
+ * bits 25-22 (4 bits) indicate a letter:
+ * 0000(0) - v
+ * 0001(1) - r
+ * 0010(2) - k
+ * 0011(3) - t
+ * remaining combinations reserved (w...)
+ * bits 21-18 (4 bits) indicate a number:
+ * 0000(0) - 1
+ * 0001(1) - 2
+ * 0010(2) - 3
+ * 0011(3) - 4
+ * remaining combinations reserved
+ * bits 17-0 (18 bits) - length of the prime field in bits
+ *
+ * For now this is mostly used for elliptic curves. For any other keys key_bit_len can be
+ * passed just as a number of bits (2 most significant bits set to 00, 30 bits for bit length).
+ *
+ * For elliptic curves don't use those defines directly, use enums in yaca_key_bit_length_ec_e.
+ * Not all combinations are valid and other valid combinations are not guaranteed to be
+ * implemented (they most surely aren't).
+ */
+
+/** @cond Don't include those defines in doxygen, they are not to be used directly */
+#define YACA_KEY_LEN_TYPE_MASK (3U << 30)
+
+#define YACA_KEY_LEN_TYPE_REGULAR (0U << 30)
+#define YACA_KEY_LEN_TYPE_EC (1U << 30)
+
+#define YACA_KEY_LEN_EC_PRIME (0U << 26)
+#define YACA_KEY_LEN_EC_SECP (1U << 26)
+#define YACA_KEY_LEN_EC_SECT (2U << 26)
+#define YACA_KEY_LEN_EC_BRAINPOOL (3U << 26)
+
+#define YACA_KEY_LEN_EC_V (0U << 22)
+#define YACA_KEY_LEN_EC_R (1U << 22)
+#define YACA_KEY_LEN_EC_K (2U << 22)
+#define YACA_KEY_LEN_EC_T (3U << 22)
+
+#define YACA_KEY_LEN_EC_1 (0U << 18)
+#define YACA_KEY_LEN_EC_2 (1U << 18)
+#define YACA_KEY_LEN_EC_3 (2U << 18)
+#define YACA_KEY_LEN_EC_4 (3U << 18)
+/** @endcond */
+
/**
* @brief The context handle.
*
} yaca_key_bit_length_e;
/**
+ * @brief Enumeration of YACA elliptic curve types with their bit lengths.
+ * It's meant to be passed or returned as a @a key_bit_len param
+ * in appropriate functions when dealing with elliptic curves.
+ *
+ * @since_tizen 3.0
+ */
+typedef enum {
+ /** Elliptic curve prime192v1 */
+ YACA_KEY_LENGTH_EC_PRIME192V1 = YACA_KEY_LEN_TYPE_EC | YACA_KEY_LEN_EC_PRIME | YACA_KEY_LEN_EC_V | YACA_KEY_LEN_EC_1 | 192U,
+ /** Elliptic curve prime256v1 */
+ YACA_KEY_LENGTH_EC_PRIME256V1 = YACA_KEY_LEN_TYPE_EC | YACA_KEY_LEN_EC_PRIME | YACA_KEY_LEN_EC_V | YACA_KEY_LEN_EC_1 | 256U,
+ /** Elliptic curve secp256k1 */
+ YACA_KEY_LENGTH_EC_SECP256K1 = YACA_KEY_LEN_TYPE_EC | YACA_KEY_LEN_EC_SECP | YACA_KEY_LEN_EC_K | YACA_KEY_LEN_EC_1 | 256U,
+ /** Elliptic curve secp384r1 */
+ YACA_KEY_LENGTH_EC_SECP384R1 = YACA_KEY_LEN_TYPE_EC | YACA_KEY_LEN_EC_SECP | YACA_KEY_LEN_EC_R | YACA_KEY_LEN_EC_1 | 384U,
+ /** Elliptic curve secp521r1 */
+ YACA_KEY_LENGTH_EC_SECP521R1 = YACA_KEY_LEN_TYPE_EC | YACA_KEY_LEN_EC_SECP | YACA_KEY_LEN_EC_R | YACA_KEY_LEN_EC_1 | 521U
+} yaca_key_bit_length_ec_e;
+
+/**
* @brief Enumeration of YACA message digest algorithms.
*
* @since_tizen 3.0
#include <yaca_crypto.h>
#include <yaca_error.h>
#include <yaca_key.h>
+#include <yaca_types.h>
#include "internal.h"
+const static struct {
+ size_t key_bit_len_ec;
+ int nid;
+} EC_NID_PAIRS[] = {
+ {YACA_KEY_LENGTH_EC_PRIME192V1, NID_X9_62_prime192v1},
+ {YACA_KEY_LENGTH_EC_PRIME256V1, NID_X9_62_prime256v1},
+ {YACA_KEY_LENGTH_EC_SECP256K1, NID_secp256k1},
+ {YACA_KEY_LENGTH_EC_SECP384R1, NID_secp384r1},
+ {YACA_KEY_LENGTH_EC_SECP521R1, NID_secp521r1}
+};
+
+const static size_t EC_NID_PAIRS_SIZE = sizeof(EC_NID_PAIRS) / sizeof(EC_NID_PAIRS[0]);
+
struct openssl_password_data {
bool password_requested;
const char *password;
{
assert(out != NULL);
+ if (key_bit_len % 8 != 0)
+ return YACA_ERROR_INVALID_PARAMETER;
+
int ret;
struct yaca_key_simple_s *nk;
size_t key_byte_len = key_bit_len / 8;
return ret;
}
+int convert_ec_to_nid(size_t key_bit_len_ec, int *nid)
+{
+ assert(nid != NULL);
+
+ size_t i;
+
+ for (i = 0; i < EC_NID_PAIRS_SIZE; ++i) {
+ if (EC_NID_PAIRS[i].key_bit_len_ec == key_bit_len_ec) {
+ *nid = EC_NID_PAIRS[i].nid;
+ return YACA_ERROR_NONE;
+ }
+ }
+
+ return YACA_ERROR_INVALID_PARAMETER;
+}
+
+size_t convert_nid_to_ec(int nid, size_t *key_bit_len_ec)
+{
+ assert(key_bit_len_ec != NULL);
+
+ size_t i;
+
+ for (i = 0; i < EC_NID_PAIRS_SIZE; ++i) {
+ if (EC_NID_PAIRS[i].nid == nid) {
+ *key_bit_len_ec = EC_NID_PAIRS[i].key_bit_len_ec;
+ return YACA_ERROR_NONE;
+ }
+ }
+
+ return YACA_ERROR_INVALID_PARAMETER;
+}
+
int generate_evp(struct yaca_key_evp_s **out, yaca_key_type_e key_type, size_t key_bit_len)
{
assert(out != NULL);
EVP_PKEY *params = NULL;
struct yaca_key_evp_s *nk;
- switch(key_type) {
+ switch (key_type) {
case YACA_KEY_TYPE_RSA_PRIV:
- assert(key_bit_len % 8 == 0);
+ if ((key_bit_len & YACA_KEY_LEN_TYPE_MASK) != YACA_KEY_LEN_TYPE_REGULAR ||
+ key_bit_len % 8 != 0)
+ return YACA_ERROR_INVALID_PARAMETER;
id = EVP_PKEY_RSA;
do_params = false;
break;
case YACA_KEY_TYPE_DSA_PRIV:
- assert(key_bit_len % 8 == 0);
-
- /* Openssl generates 512-bit key for key lengths smaller than 512. It also
- * rounds key size to multiplication of 64. */
- if (key_bit_len < 512 || key_bit_len % 64 != 0)
+ if ((key_bit_len & YACA_KEY_LEN_TYPE_MASK) != YACA_KEY_LEN_TYPE_REGULAR ||
+ /* Openssl generates 512-bit key for key lengths smaller than 512. It also
+ * rounds key size to multiplication of 64. */
+ key_bit_len < 512 || key_bit_len % 64 != 0)
return YACA_ERROR_INVALID_PARAMETER;
+
id = EVP_PKEY_DSA;
do_params = true;
break;
case YACA_KEY_TYPE_DH_PRIV:
- assert(key_bit_len % 8 == 0);
+ if ((key_bit_len & YACA_KEY_LEN_TYPE_MASK) != YACA_KEY_LEN_TYPE_REGULAR ||
+ key_bit_len % 8 != 0)
+ return YACA_ERROR_INVALID_PARAMETER;
id = EVP_PKEY_DH;
do_params = true;
break;
+ case YACA_KEY_TYPE_EC_PRIV:
+ if ((key_bit_len & YACA_KEY_LEN_TYPE_MASK) != YACA_KEY_LEN_TYPE_EC)
+ return YACA_ERROR_INVALID_PARAMETER;
+
+ id = EVP_PKEY_EC;
+ do_params = true;
+ break;
default:
return YACA_ERROR_INVALID_PARAMETER;
}
goto exit;
}
- switch(id) {
+ switch (id) {
case EVP_PKEY_DSA:
ret = EVP_PKEY_CTX_set_dsa_paramgen_bits(pctx, key_bit_len);
break;
case EVP_PKEY_DH:
ret = EVP_PKEY_CTX_set_dh_paramgen_prime_len(pctx, key_bit_len);
break;
+ case EVP_PKEY_EC: {
+ int nid;
+ ret = convert_ec_to_nid(key_bit_len, &nid);
+ if (ret != YACA_ERROR_NONE)
+ goto exit;
+ ret = EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, nid);
+ if (ret == 1)
+ ret = EVP_PKEY_CTX_set_ec_param_enc(pctx, OPENSSL_EC_NAMED_CURVE);
+ break;
+ }
default:
/* We shouldn't be here */
assert(false);
ret = YACA_ERROR_INTERNAL;
goto exit;
}
+
if (ret != 1) {
ret = YACA_ERROR_INTERNAL;
ERROR_DUMP(ret);
case YACA_KEY_TYPE_DSA_PRIV:
case YACA_KEY_TYPE_DH_PUB:
case YACA_KEY_TYPE_DH_PRIV:
+ case YACA_KEY_TYPE_EC_PUB:
+ case YACA_KEY_TYPE_EC_PRIV:
k = (struct yaca_key_evp_s *)key;
/* sanity check */
if (evp_key != NULL) {
int ret;
- // TODO: handle ECC keys when they're implemented
- ret = EVP_PKEY_bits(evp_key->evp);
- if (ret <= 0) {
- ret = YACA_ERROR_INTERNAL;
- ERROR_DUMP(ret);
- return ret;
- }
+ switch (evp_key->key.type) {
+ case YACA_KEY_TYPE_RSA_PRIV:
+ case YACA_KEY_TYPE_RSA_PUB:
+ case YACA_KEY_TYPE_DSA_PRIV:
+ case YACA_KEY_TYPE_DSA_PUB:
+ case YACA_KEY_TYPE_DH_PRIV:
+ case YACA_KEY_TYPE_DH_PUB:
+ ret = EVP_PKEY_bits(evp_key->evp);
+ if (ret <= 0) {
+ ret = YACA_ERROR_INTERNAL;
+ ERROR_DUMP(ret);
+ return ret;
+ }
- *key_bit_len = ret;
- return YACA_ERROR_NONE;
+ *key_bit_len = ret;
+ return YACA_ERROR_NONE;
+ case YACA_KEY_TYPE_EC_PRIV:
+ case YACA_KEY_TYPE_EC_PUB: {
+ assert(EVP_PKEY_type(evp_key->evp->type) == EVP_PKEY_EC);
+
+ const EC_KEY *eck = EVP_PKEY_get0(evp_key->evp);
+ const EC_GROUP *ecg = EC_KEY_get0_group(eck);
+ int flags = EC_GROUP_get_asn1_flag(ecg);
+ int nid;
+
+ if (!(flags & OPENSSL_EC_NAMED_CURVE))
+ /* This is case of a custom (not named) curve, that can happen when someone
+ imports such a key into YACA. There is nothing that can be returned here */
+ return YACA_ERROR_INVALID_PARAMETER;
+
+ nid = EC_GROUP_get_curve_name(ecg);
+ return convert_nid_to_ec(nid, key_bit_len);
+ }
+ default:
+ /* We shouldn't be here */
+ assert(false);
+ return YACA_ERROR_INTERNAL;
+ }
}
return YACA_ERROR_INVALID_PARAMETER;
struct yaca_key_simple_s *nk_simple = NULL;
struct yaca_key_evp_s *nk_evp = NULL;
- if (key == NULL || key_bit_len == 0 || key_bit_len % 8 != 0)
+ if (key == NULL || key_bit_len == 0)
return YACA_ERROR_INVALID_PARAMETER;
switch (key_type) {
case YACA_KEY_TYPE_RSA_PRIV:
case YACA_KEY_TYPE_DSA_PRIV:
case YACA_KEY_TYPE_DH_PRIV:
+ case YACA_KEY_TYPE_EC_PRIV:
ret = generate_evp(&nk_evp, key_type, key_bit_len);
break;
- case YACA_KEY_TYPE_EC_PRIV:
- //TODO NOT_IMPLEMENTED
default:
return YACA_ERROR_INVALID_PARAMETER;
}
}
return YACA_ERROR_NONE;
-
}
API int yaca_key_extract_public(const yaca_key_h prv_key, yaca_key_h *pub_key)