From 742c9d7b94051d3b21f9f61a73ed6b5f3544cb82 Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 13 Dec 2016 14:05:15 +0000 Subject: Add Diffie-Hellman compute function Signed-off-by: Mat Martineau Signed-off-by: David Howells --- keyctl.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ keyutils.c | 42 ++++++++++++++++++++++++++++++++++++++++++ keyutils.h | 12 ++++++++++++ keyutils.spec | 2 +- version.lds | 9 ++++++++- 5 files changed, 115 insertions(+), 2 deletions(-) diff --git a/keyctl.c b/keyctl.c index 7e5ce6f..801a864 100644 --- a/keyctl.c +++ b/keyctl.c @@ -66,6 +66,7 @@ static nr void act_keyctl_reap(int argc, char *argv[]); static nr void act_keyctl_purge(int argc, char *argv[]); static nr void act_keyctl_invalidate(int argc, char *argv[]); static nr void act_keyctl_get_persistent(int argc, char *argv[]); +static nr void act_keyctl_dh_compute(int argc, char *argv[]); const struct command commands[] = { { act_keyctl___version, "--version", "" }, @@ -74,6 +75,7 @@ const struct command commands[] = { { act_keyctl_chown, "chown", " " }, { act_keyctl_clear, "clear", "" }, { act_keyctl_describe, "describe", "" }, + { act_keyctl_dh_compute, "dh_compute", " " }, { act_keyctl_instantiate, "instantiate"," " }, { act_keyctl_invalidate,"invalidate", "" }, { act_keyctl_get_persistent, "get_persistent", " []" }, @@ -1625,6 +1627,56 @@ static void act_keyctl_get_persistent(int argc, char *argv[]) exit(0); } +/*****************************************************************************/ +/* + * Perform Diffie-Hellman computation + */ +static void act_keyctl_dh_compute(int argc, char *argv[]) +{ + key_serial_t priv, prime, base; + void *buffer; + char *p; + int ret, sep, col; + + if (argc != 4) + format(); + + priv = get_key_id(argv[1]); + prime = get_key_id(argv[2]); + base = get_key_id(argv[3]); + + ret = keyctl_dh_compute_alloc(priv, prime, base, &buffer); + if (ret < 0) + error("keyctl_dh_compute_alloc"); + + /* hexdump the contents */ + printf("%u bytes of data in result:\n", ret); + + sep = 0; + col = 0; + p = buffer; + + do { + if (sep) { + putchar(sep); + sep = 0; + } + + printf("%02hhx", *p); + p++; + + col++; + if (col % 32 == 0) + sep = '\n'; + else if (col % 4 == 0) + sep = ' '; + + } while (--ret > 0); + + printf("\n"); + exit(0); +} + /*****************************************************************************/ /* * parse a key identifier diff --git a/keyutils.c b/keyutils.c index 8856c8a..a6325d0 100644 --- a/keyutils.c +++ b/keyutils.c @@ -234,6 +234,16 @@ long keyctl_get_persistent(uid_t uid, key_serial_t id) return keyctl(KEYCTL_GET_PERSISTENT, uid, id); } +long keyctl_dh_compute(key_serial_t priv, key_serial_t prime, + key_serial_t base, char *buffer, size_t buflen) +{ + struct keyctl_dh_params params = { .priv = priv, + .prime = prime, + .base = base }; + + return keyctl(KEYCTL_DH_COMPUTE, ¶ms, buffer, buflen, 0); +} + /*****************************************************************************/ /* * fetch key description into an allocated buffer @@ -343,6 +353,38 @@ int keyctl_get_security_alloc(key_serial_t id, char **_buffer) return ret - 1; } +/*****************************************************************************/ +/* + * fetch DH computation results into an allocated buffer + * - resulting buffer has an extra NUL added to the end + * - returns count (not including extraneous NUL) + */ +int keyctl_dh_compute_alloc(key_serial_t priv, key_serial_t prime, + key_serial_t base, void **_buffer) +{ + char *buf; + long buflen, ret; + + ret = keyctl_dh_compute(priv, prime, base, NULL, 0); + if (ret < 0) + return -1; + + buflen = ret; + buf = malloc(buflen + 1); + if (!buf) + return -1; + + ret = keyctl_dh_compute(priv, prime, base, buf, buflen); + if (ret < 0) { + free(buf); + return -1; + } + + buf[ret] = 0; + *_buffer = buf; + return ret; +} + /* * Depth-first recursively apply a function over a keyring tree */ diff --git a/keyutils.h b/keyutils.h index fc8495d..a69fa7a 100644 --- a/keyutils.h +++ b/keyutils.h @@ -99,6 +99,14 @@ typedef uint32_t key_perm_t; #define KEYCTL_INSTANTIATE_IOV 20 /* instantiate a partially constructed key */ #define KEYCTL_INVALIDATE 21 /* invalidate a key */ #define KEYCTL_GET_PERSISTENT 22 /* get a user's persistent keyring */ +#define KEYCTL_DH_COMPUTE 23 /* Compute Diffie-Hellman values */ + +/* keyctl structures */ +struct keyctl_dh_params { + key_serial_t priv; + key_serial_t prime; + key_serial_t base; +}; /* * syscall wrappers @@ -153,6 +161,8 @@ extern long keyctl_instantiate_iov(key_serial_t id, key_serial_t ringid); extern long keyctl_invalidate(key_serial_t id); extern long keyctl_get_persistent(uid_t uid, key_serial_t id); +extern long keyctl_dh_compute(key_serial_t priv, key_serial_t prime, + key_serial_t base, char *buffer, size_t buflen); /* * utilities @@ -160,6 +170,8 @@ extern long keyctl_get_persistent(uid_t uid, key_serial_t id); extern int keyctl_describe_alloc(key_serial_t id, char **_buffer); extern int keyctl_read_alloc(key_serial_t id, void **_buffer); extern int keyctl_get_security_alloc(key_serial_t id, char **_buffer); +extern int keyctl_dh_compute_alloc(key_serial_t priv, key_serial_t prime, + key_serial_t base, void **_buffer); typedef int (*recursive_key_scanner_t)(key_serial_t parent, key_serial_t key, char *desc, int desc_len, void *data); diff --git a/keyutils.spec b/keyutils.spec index 3312f84..895e085 100644 --- a/keyutils.spec +++ b/keyutils.spec @@ -2,7 +2,7 @@ %define verminor 5.9 %define version %{vermajor}.%{verminor} %define libapivermajor 1 -%define libapiversion %{libapivermajor}.5 +%define libapiversion %{libapivermajor}.6 # % define buildid .local diff --git a/version.lds b/version.lds index 5f07463..2bfed13 100644 --- a/version.lds +++ b/version.lds @@ -23,7 +23,7 @@ KEYUTILS_0.3 { keyctl_set_reqkey_keyring; keyctl_unlink; keyctl_update; - + }; KEYUTILS_1.0 { @@ -61,3 +61,10 @@ KEYUTILS_1.5 { find_key_by_type_and_desc; } KEYUTILS_1.4; + +KEYUTILS_1.6 { + /* management functions */ + keyctl_dh_compute; + keyctl_dh_compute_alloc; + +} KEYUTILS_1.5; -- cgit v1.2.1