summaryrefslogtreecommitdiffstats
path: root/ncr-key-wrap.c
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2010-08-19 18:20:26 +0200
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2010-08-19 18:20:26 +0200
commit5507ea6f51bd227ce4af661d550ad4d4de80674b (patch)
tree324958e4792047c42f9cc41041c5e0c7c0843103 /ncr-key-wrap.c
parenta7befd9b8fba6f6d777f7d8436154dc62f1fa652 (diff)
downloadkernel-crypto-5507ea6f51bd227ce4af661d550ad4d4de80674b.tar.gz
kernel-crypto-5507ea6f51bd227ce4af661d550ad4d4de80674b.tar.xz
kernel-crypto-5507ea6f51bd227ce4af661d550ad4d4de80674b.zip
Added KEY_WRAPPING flag that allows a key to be used for wrapping other keys.
Only superuser can enable this flag. Prevent short keys to wrap longer ones. Added initial stuff for supporting wrapping of private and public keys.
Diffstat (limited to 'ncr-key-wrap.c')
-rw-r--r--ncr-key-wrap.c57
1 files changed, 49 insertions, 8 deletions
diff --git a/ncr-key-wrap.c b/ncr-key-wrap.c
index 0c56def27f7..eb68d92de05 100644
--- a/ncr-key-wrap.c
+++ b/ncr-key-wrap.c
@@ -430,6 +430,37 @@ cleanup:
return ret;
}
+/* will check if the kek is of equal or higher security level than
+ * wkey. To prevent encrypting a 256 bit key with an 128 bit one.
+ */
+int check_key_level(struct key_item_st* kek, struct key_item_st* wkey)
+{
+int kek_level, wkey_level;
+
+ /* allow wrapping of public keys with any key */
+ if (wkey->type == NCR_KEY_TYPE_PUBLIC)
+ return 0;
+
+ kek_level = _ncr_key_get_sec_level(kek);
+ if (kek_level < 0) {
+ err();
+ return kek_level;
+ }
+
+ wkey_level = _ncr_key_get_sec_level(wkey);
+ if (wkey_level < 0) {
+ err();
+ return wkey_level;
+ }
+
+ if (wkey_level > kek_level) {
+ err();
+ return -EPERM;
+ }
+
+ return 0;
+}
+
int ncr_key_wrap(struct ncr_lists *lst, void __user* arg)
{
struct ncr_key_wrap_st wrap;
@@ -462,6 +493,18 @@ int ret;
goto fail;
}
+ if (!(key->flags & NCR_KEY_FLAG_WRAPPING)) {
+ err();
+ ret = -EPERM;
+ goto fail;
+ }
+
+ ret = check_key_level(key, wkey);
+ if (ret < 0) {
+ err();
+ goto fail;
+ }
+
data_size = wrap.io_size;
data = kmalloc(data_size, GFP_KERNEL);
if (data == NULL) {
@@ -539,6 +582,12 @@ int ret;
goto fail;
}
+ if (!(key->flags & NCR_KEY_FLAG_WRAPPING)) {
+ err();
+ ret = -EPERM;
+ goto fail;
+ }
+
data_size = wrap.io_size;
data = kmalloc(data_size, GFP_KERNEL);
if (data == NULL) {
@@ -601,12 +650,6 @@ int ret;
return ret;
}
- if (!(wkey->flags & NCR_KEY_FLAG_WRAPPABLE)) {
- err();
- ret = -EPERM;
- goto fail;
- }
-
data_size = wrap.io_size;
data = kmalloc(data_size, GFP_KERNEL);
if (data == NULL) {
@@ -698,8 +741,6 @@ int ret;
goto fail;
}
- wkey->flags = NCR_KEY_FLAG_WRAPPABLE;
-
ret = _unwrap_aes_rfc5649(sdata, &sdata_size, &master_key, data, data_size, NULL, 0);
if (ret < 0) {
err();