diff options
Diffstat (limited to 'ncr-key-wrap.c')
-rw-r--r-- | ncr-key-wrap.c | 117 |
1 files changed, 62 insertions, 55 deletions
diff --git a/ncr-key-wrap.c b/ncr-key-wrap.c index 7ea70cfc847..a15d3710653 100644 --- a/ncr-key-wrap.c +++ b/ncr-key-wrap.c @@ -36,6 +36,12 @@ #define KEY_WRAP_VERSION 0 +/* To be further checked. If the current implemented key wrapping mechanism + * has no issues, it might be possible to relax the requirement for + * privileged key wrapping. + */ +#define KEY_WRAP_IS_PRIVILEGED + typedef uint8_t val64_t[8]; static const val64_t initA = "\xA6\xA6\xA6\xA6\xA6\xA6\xA6\xA6"; @@ -537,6 +543,13 @@ const void *iv; size_t data_size, iv_size; int ret; +#ifdef KEY_WRAP_IS_PRIVILEGED + if (current_euid() != 0) { + err(); + return -EPERM; + } +#endif + if (wrap->buffer_size < 0) { err(); return -EINVAL; @@ -640,6 +653,13 @@ void* data = NULL; size_t data_size; int ret; +#ifdef KEY_WRAP_IS_PRIVILEGED + if (current_euid() != 0) { + err(); + return -EPERM; + } +#endif + ret = ncr_key_item_get_write(&wkey, lst, wrap->dest_key); if (ret < 0) { err(); @@ -831,8 +851,8 @@ fail: /* Packed data are DER encoded: * PackedData ::= SEQUENCE { * version INTEGER { v1(0) } - * type INTEGER { secret_key(0), rsa_privkey(1), rsa_pubkey(2), dsa_privkey(3), dsa_pubkey(4), - * dh_privkey(5), dh_pubkey(6) }, + * algorithm OBJECT IDENTIFIER, + * type INTEGER { secret_key(0), public(1), private(2) }, * data OCTET STRING * } * @@ -847,6 +867,7 @@ static int key_to_packed_data( uint8_t** sdata, size_t * sdata_size, const struc unsigned long version = KEY_WRAP_VERSION; unsigned long type; unsigned long derlen; + const oid_st* oid; *sdata_size = KEY_DATA_MAX_SIZE; pkey = kmalloc(*sdata_size, GFP_KERNEL); @@ -875,37 +896,25 @@ static int key_to_packed_data( uint8_t** sdata, size_t * sdata_size, const struc goto fail; } - switch (key->algorithm->algo) { - case NCR_ALG_RSA: - if (key->type == NCR_KEY_TYPE_PUBLIC) - type = 2; - else type = 1; - break; - case NCR_ALG_DSA: - if (key->type == NCR_KEY_TYPE_PUBLIC) - type = 4; - else type = 3; - break; - case NCR_ALG_DH: - if (key->type == NCR_KEY_TYPE_PUBLIC) - type = 6; - else type = 5; - break; - default: - /* unsupported yet */ - ret = -EINVAL; - err(); - goto fail; - } - + if (key->type == NCR_KEY_TYPE_PUBLIC) + type = 1; + else type = 2; } else { err(); ret = -EINVAL; goto fail; } + + oid = _ncr_properties_to_oid(key->algorithm, pkey_size); + if (oid == NULL) { + err(); + ret = -EOPNOTSUPP; + goto fail; + } err = der_encode_sequence_multi(derkey, &derlen, LTC_ASN1_SHORT_INTEGER, 1UL, &version, + LTC_ASN1_OBJECT_IDENTIFIER, oid->OIDlen, oid->OID, LTC_ASN1_SHORT_INTEGER, 1UL, &type, LTC_ASN1_OCTET_STRING, (unsigned long)pkey_size, pkey, LTC_ASN1_EOL, 0UL, NULL); @@ -934,42 +943,17 @@ inline static int packed_type_to_key_type(unsigned long type, struct key_item_st switch(type) { case 0: key->type = NCR_KEY_TYPE_SECRET; - key->algorithm = _ncr_algo_to_properties("cbc(aes)"); break; case 1: - key->type = NCR_KEY_TYPE_PRIVATE; - key->algorithm = _ncr_algo_to_properties("rsa"); - break; - case 2: - key->type = NCR_KEY_TYPE_PUBLIC; - key->algorithm = _ncr_algo_to_properties("rsa"); - break; - case 3: - key->type = NCR_KEY_TYPE_PRIVATE; - key->algorithm = _ncr_algo_to_properties("dsa"); - break; - case 4: key->type = NCR_KEY_TYPE_PUBLIC; - key->algorithm = _ncr_algo_to_properties("dsa"); break; - case 5: + case 2: key->type = NCR_KEY_TYPE_PRIVATE; - key->algorithm = _ncr_algo_to_properties("dh"); - break; - case 6: - key->type = NCR_KEY_TYPE_PUBLIC; - key->algorithm = _ncr_algo_to_properties("dh"); break; default: err(); return -EINVAL; } - - if (key->algorithm == NULL) { - err(); - return -EINVAL; - } - return 0; } @@ -981,9 +965,10 @@ static int key_from_packed_data(struct nlattr *tb[], struct key_item_st *key, const void *data, size_t data_size) { ltc_asn1_list list[6]; - int ret, i = 0, pkey_size, err; + int ret, i, pkey_size, err; unsigned long version, type; uint8_t * pkey = NULL; + oid_st oid; if (data_size > DER_KEY_MAX_SIZE) { err(); @@ -997,10 +982,16 @@ static int key_from_packed_data(struct nlattr *tb[], struct key_item_st *key, return -ENOMEM; } + i = 0; + list[i].type = LTC_ASN1_SHORT_INTEGER; list[i].size = 1; list[i++].data = &version; + list[i].type = LTC_ASN1_OBJECT_IDENTIFIER; + list[i].size = sizeof(oid.OID)/sizeof(oid.OID[0]); + list[i++].data = oid.OID; + list[i].type = LTC_ASN1_SHORT_INTEGER; list[i].size = 1; list[i++].data = &type; @@ -1015,14 +1006,15 @@ static int key_from_packed_data(struct nlattr *tb[], struct key_item_st *key, ret = _ncr_tomerr(err); goto fail; } - + if (version != KEY_WRAP_VERSION) { err(); ret = -EINVAL; goto fail; } - - pkey_size = list[2].size; + + oid.OIDlen = list[1].size; + pkey_size = list[3].size; ret = packed_type_to_key_type(type, key); if (ret < 0) { @@ -1030,11 +1022,26 @@ static int key_from_packed_data(struct nlattr *tb[], struct key_item_st *key, goto fail; } + key->algorithm = _ncr_oid_to_properties(&oid); + if (key->algorithm == NULL) { + err(); + ret = -EINVAL; + goto fail; + } + ret = ncr_key_update_flags(key, tb[NCR_ATTR_KEY_FLAGS]); if (ret != 0) { err(); return ret; } + + +#ifndef KEY_WRAP_IS_PRIVILEGED + /* Do not allow key unwrapping to result to exportable keys + */ + if (current_euid() != 0) + key->flags &= (~NCR_KEY_FLAG_EXPORTABLE); +#endif if (key->type == NCR_KEY_TYPE_SECRET) { if (data_size > NCR_CIPHER_MAX_KEY_LEN) { |