summaryrefslogtreecommitdiff
path: root/drivers/s390/crypto/pkey_pckmo.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/crypto/pkey_pckmo.c')
-rw-r--r--drivers/s390/crypto/pkey_pckmo.c91
1 files changed, 76 insertions, 15 deletions
diff --git a/drivers/s390/crypto/pkey_pckmo.c b/drivers/s390/crypto/pkey_pckmo.c
index 30a9d2f64853..d2c2c61f449b 100644
--- a/drivers/s390/crypto/pkey_pckmo.c
+++ b/drivers/s390/crypto/pkey_pckmo.c
@@ -18,10 +18,67 @@
#include "pkey_base.h"
/*
- * Check key blob for known and supported here.
+ * Prototypes
*/
+
+static bool is_pckmo_key(const u8 *key, u32 keylen);
+static int pckmo_key2protkey(const u8 *key, u32 keylen,
+ u8 *protkey, u32 *protkeylen, u32 *protkeytype);
+static int pckmo_gen_protkey(u32 keytype,
+ u8 *protkey, u32 *protkeylen, u32 *protkeytype);
+static int pckmo_clr2protkey(u32 keytype, const u8 *clrkey, u32 clrkeylen,
+ u8 *protkey, u32 *protkeylen, u32 *protkeytype);
+static int pckmo_verify_protkey(const u8 *protkey, u32 protkeylen,
+ u32 protkeytype);
+
+/*
+ * Wrapper functions
+ */
+
bool pkey_is_pckmo_key(const u8 *key, u32 keylen)
{
+ return is_pckmo_key(key, keylen);
+}
+
+int pkey_pckmo_key2protkey(u16 _card, u16 _dom,
+ const u8 *key, u32 keylen,
+ u8 *protkey, u32 *protkeylen, u32 *keyinfo)
+{
+ return pckmo_key2protkey(key, keylen,
+ protkey, protkeylen, keyinfo);
+}
+
+int pkey_pckmo_gen_key(u16 _card, u16 _dom,
+ u32 keytype, u32 _keysubtype,
+ u32 _keybitsize, u32 _flags,
+ u8 *keybuf, u32 *keybuflen, u32 *keyinfo)
+{
+ return pckmo_gen_protkey(keytype,
+ keybuf, keybuflen, keyinfo);
+}
+
+int pkey_pckmo_clr2key(u16 _card, u16 _dom,
+ u32 keytype, u32 _keysubtype,
+ u32 _keybitsize, u32 _flags,
+ const u8 *clrkey, u32 clrkeylen,
+ u8 *keybuf, u32 *keybuflen, u32 *keyinfo)
+{
+ return pckmo_clr2protkey(keytype, clrkey, clrkeylen,
+ keybuf, keybuflen, keyinfo);
+}
+
+int pkey_pckmo_verifykey(const u8 *key, u32 keylen,
+ u16 *_card, u16 *_dom,
+ u32 *keytype, u32 *_keybitsize, u32 *_flags)
+{
+ return pckmo_verify_protkey(key, keylen, *keytype);
+}
+
+/*
+ * Check key blob for known and supported here.
+ */
+static bool is_pckmo_key(const u8 *key, u32 keylen)
+{
struct keytoken_header *hdr = (struct keytoken_header *)key;
struct clearkeytoken *t = (struct clearkeytoken *)key;
@@ -55,8 +112,8 @@ bool pkey_is_pckmo_key(const u8 *key, u32 keylen)
}
}
-int pkey_pckmo_key2protkey(const u8 *key, u32 keylen,
- u8 *protkey, u32 *protkeylen, u32 *protkeytype)
+static int pckmo_key2protkey(const u8 *key, u32 keylen,
+ u8 *protkey, u32 *protkeylen, u32 *protkeytype)
{
struct keytoken_header *hdr = (struct keytoken_header *)key;
int rc = -EINVAL;
@@ -73,8 +130,7 @@ int pkey_pckmo_key2protkey(const u8 *key, u32 keylen,
if (keylen != sizeof(struct protaeskeytoken))
goto out;
t = (struct protaeskeytoken *)key;
- rc = pkey_pckmo_verify_protkey(t->protkey, t->len,
- t->keytype);
+ rc = pckmo_verify_protkey(t->protkey, t->len, t->keytype);
if (rc)
goto out;
memcpy(protkey, t->protkey, t->len);
@@ -123,8 +179,8 @@ int pkey_pckmo_key2protkey(const u8 *key, u32 keylen,
__func__, t->len);
goto out;
}
- rc = pkey_pckmo_clr2protkey(t->keytype, t->clearkey,
- protkey, protkeylen, protkeytype);
+ rc = pckmo_clr2protkey(t->keytype, t->clearkey, t->len,
+ protkey, protkeylen, protkeytype);
break;
}
default:
@@ -143,8 +199,8 @@ out:
* Currently only the generation of AES protected keys
* is supported.
*/
-int pkey_pckmo_gen_protkey(u32 keytype, u8 *protkey,
- u32 *protkeylen, u32 *protkeytype)
+static int pckmo_gen_protkey(u32 keytype, u8 *protkey,
+ u32 *protkeylen, u32 *protkeytype)
{
u8 clrkey[32];
int keysize;
@@ -161,8 +217,8 @@ int pkey_pckmo_gen_protkey(u32 keytype, u8 *protkey,
get_random_bytes(clrkey, keysize);
/* convert it to a dummy protected key */
- rc = pkey_pckmo_clr2protkey(keytype, clrkey,
- protkey, protkeylen, protkeytype);
+ rc = pckmo_clr2protkey(keytype, clrkey, keysize,
+ protkey, protkeylen, protkeytype);
if (rc)
goto out;
@@ -177,8 +233,8 @@ out:
/*
* Create a protected key from a clear key value via PCKMO instruction.
*/
-int pkey_pckmo_clr2protkey(u32 keytype, const u8 *clrkey,
- u8 *protkey, u32 *protkeylen, u32 *protkeytype)
+static int pckmo_clr2protkey(u32 keytype, const u8 *clrkey, u32 clrkeylen,
+ u8 *protkey, u32 *protkeylen, u32 *protkeytype)
{
/* mask of available pckmo subfunctions */
static cpacf_mask_t pckmo_functions;
@@ -243,6 +299,11 @@ int pkey_pckmo_clr2protkey(u32 keytype, const u8 *clrkey,
goto out;
}
+ if (clrkeylen && clrkeylen < keysize) {
+ PKEY_DBF_ERR("%s clear key size too small: %u < %d\n",
+ __func__, clrkeylen, keysize);
+ goto out;
+ }
if (*protkeylen < keysize + AES_WK_VP_SIZE) {
PKEY_DBF_ERR("%s prot key buffer size too small: %u < %d\n",
__func__, *protkeylen, keysize + AES_WK_VP_SIZE);
@@ -288,8 +349,8 @@ out:
* Verify a protected key blob.
* Currently only AES protected keys are supported.
*/
-int pkey_pckmo_verify_protkey(const u8 *protkey, u32 protkeylen,
- u32 protkeytype)
+static int pckmo_verify_protkey(const u8 *protkey, u32 protkeylen,
+ u32 protkeytype)
{
struct {
u8 iv[AES_BLOCK_SIZE];