summaryrefslogtreecommitdiffstats
path: root/ncr-key-wrap.c
diff options
context:
space:
mode:
Diffstat (limited to 'ncr-key-wrap.c')
-rw-r--r--ncr-key-wrap.c117
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) {