Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

s390/pkey: Add AES xts and HMAC clear key token support

Add support for deriving protected keys from clear key token for
AES xts and HMAC keys via PCKMO instruction. Add support for
protected key generation and unwrap of protected key tokens for
these key types. Furthermore 4 new sysfs attributes are introduced:

- /sys/devices/virtual/misc/pkey/protkey/protkey_aes_xts_128
- /sys/devices/virtual/misc/pkey/protkey/protkey_aes_xts_256
- /sys/devices/virtual/misc/pkey/protkey/protkey_hmac_512
- /sys/devices/virtual/misc/pkey/protkey/protkey_hmac_1024

Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>

authored by

Harald Freudenberger and committed by
Heiko Carstens
fd197556 8fe32188

+240 -13
+4
arch/s390/include/uapi/asm/pkey.h
··· 41 41 #define PKEY_KEYTYPE_ECC_P521 7 42 42 #define PKEY_KEYTYPE_ECC_ED25519 8 43 43 #define PKEY_KEYTYPE_ECC_ED448 9 44 + #define PKEY_KEYTYPE_AES_XTS_128 10 45 + #define PKEY_KEYTYPE_AES_XTS_256 11 46 + #define PKEY_KEYTYPE_HMAC_512 12 47 + #define PKEY_KEYTYPE_HMAC_1024 13 44 48 45 49 /* the newer ioctls use a pkey_key_type enum for type information */ 46 50 enum pkey_key_type {
+13 -2
drivers/s390/crypto/pkey_base.h
··· 33 33 #define MAXAPQNSINLIST 64 /* max 64 apqns within a apqn list */ 34 34 #define AES_WK_VP_SIZE 32 /* Size of WK VP block appended to a prot key */ 35 35 36 - /* inside view of a protected key token (only type 0x00 version 0x01) */ 36 + /* inside view of a generic protected key token */ 37 + struct protkeytoken { 38 + u8 type; /* 0x00 for PAES specific key tokens */ 39 + u8 res0[3]; 40 + u8 version; /* should be 0x01 for protected key token */ 41 + u8 res1[3]; 42 + u32 keytype; /* key type, one of the PKEY_KEYTYPE values */ 43 + u32 len; /* bytes actually stored in protkey[] */ 44 + u8 protkey[]; /* the protected key blob */ 45 + } __packed; 46 + 47 + /* inside view of a protected AES key token */ 37 48 struct protaeskeytoken { 38 49 u8 type; /* 0x00 for PAES specific key tokens */ 39 50 u8 res0[3]; 40 - u8 version; /* should be 0x01 for protected AES key token */ 51 + u8 version; /* should be 0x01 for protected key token */ 41 52 u8 res1[3]; 42 53 u32 keytype; /* key type, one of the PKEY_KEYTYPE values */ 43 54 u32 len; /* bytes actually stored in protkey[] */
+91 -11
drivers/s390/crypto/pkey_pckmo.c
··· 47 47 case PKEY_KEYTYPE_ECC_P521: 48 48 case PKEY_KEYTYPE_ECC_ED25519: 49 49 case PKEY_KEYTYPE_ECC_ED448: 50 + case PKEY_KEYTYPE_AES_XTS_128: 51 + case PKEY_KEYTYPE_AES_XTS_256: 52 + case PKEY_KEYTYPE_HMAC_512: 53 + case PKEY_KEYTYPE_HMAC_1024: 50 54 return true; 51 55 default: 52 56 return false; ··· 85 81 static cpacf_mask_t pckmo_functions; 86 82 87 83 int keysize, rc = -EINVAL; 88 - u8 paramblock[112]; 84 + u8 paramblock[160]; 89 85 u32 pkeytype; 90 86 long fc; 91 87 ··· 137 133 keysize = 64; 138 134 pkeytype = PKEY_KEYTYPE_ECC; 139 135 fc = CPACF_PCKMO_ENC_ECC_ED448_KEY; 136 + break; 137 + case PKEY_KEYTYPE_AES_XTS_128: 138 + /* 2x16 byte keys, 32 byte aes wkvp, total 64 bytes */ 139 + keysize = 32; 140 + pkeytype = PKEY_KEYTYPE_AES_XTS_128; 141 + fc = CPACF_PCKMO_ENC_AES_XTS_128_DOUBLE_KEY; 142 + break; 143 + case PKEY_KEYTYPE_AES_XTS_256: 144 + /* 2x32 byte keys, 32 byte aes wkvp, total 96 bytes */ 145 + keysize = 64; 146 + pkeytype = PKEY_KEYTYPE_AES_XTS_256; 147 + fc = CPACF_PCKMO_ENC_AES_XTS_256_DOUBLE_KEY; 148 + break; 149 + case PKEY_KEYTYPE_HMAC_512: 150 + /* 64 byte key, 32 byte aes wkvp, total 96 bytes */ 151 + keysize = 64; 152 + pkeytype = PKEY_KEYTYPE_HMAC_512; 153 + fc = CPACF_PCKMO_ENC_HMAC_512_KEY; 154 + break; 155 + case PKEY_KEYTYPE_HMAC_1024: 156 + /* 128 byte key, 32 byte aes wkvp, total 160 bytes */ 157 + keysize = 128; 158 + pkeytype = PKEY_KEYTYPE_HMAC_1024; 159 + fc = CPACF_PCKMO_ENC_HMAC_1024_KEY; 140 160 break; 141 161 default: 142 162 PKEY_DBF_ERR("%s unknown/unsupported keytype %u\n", ··· 288 260 289 261 switch (hdr->version) { 290 262 case TOKVER_PROTECTED_KEY: { 291 - struct protaeskeytoken *t; 263 + struct protkeytoken *t = (struct protkeytoken *)key; 292 264 293 - if (keylen != sizeof(struct protaeskeytoken)) 265 + if (keylen < sizeof(*t)) 294 266 goto out; 295 - t = (struct protaeskeytoken *)key; 296 - rc = pckmo_verify_protkey(t->protkey, t->len, t->keytype); 297 - if (rc) 267 + switch (t->keytype) { 268 + case PKEY_KEYTYPE_AES_128: 269 + case PKEY_KEYTYPE_AES_192: 270 + case PKEY_KEYTYPE_AES_256: 271 + if (keylen != sizeof(struct protaeskeytoken)) 272 + goto out; 273 + rc = pckmo_verify_protkey(t->protkey, t->len, 274 + t->keytype); 275 + if (rc) 276 + goto out; 277 + break; 278 + case PKEY_KEYTYPE_AES_XTS_128: 279 + if (t->len != 64 || keylen != sizeof(*t) + t->len) 280 + goto out; 281 + break; 282 + case PKEY_KEYTYPE_AES_XTS_256: 283 + case PKEY_KEYTYPE_HMAC_512: 284 + if (t->len != 96 || keylen != sizeof(*t) + t->len) 285 + goto out; 286 + break; 287 + case PKEY_KEYTYPE_HMAC_1024: 288 + if (t->len != 160 || keylen != sizeof(*t) + t->len) 289 + goto out; 290 + break; 291 + default: 292 + PKEY_DBF_ERR("%s protected key token: unknown keytype %u\n", 293 + __func__, t->keytype); 298 294 goto out; 295 + } 299 296 memcpy(protkey, t->protkey, t->len); 300 297 *protkeylen = t->len; 301 298 *protkeytype = t->keytype; ··· 353 300 break; 354 301 case PKEY_KEYTYPE_ECC_ED448: 355 302 keysize = 64; 303 + break; 304 + case PKEY_KEYTYPE_AES_XTS_128: 305 + keysize = 32; 306 + break; 307 + case PKEY_KEYTYPE_AES_XTS_256: 308 + keysize = 64; 309 + break; 310 + case PKEY_KEYTYPE_HMAC_512: 311 + keysize = 64; 312 + break; 313 + case PKEY_KEYTYPE_HMAC_1024: 314 + keysize = 128; 356 315 break; 357 316 default: 358 317 break; ··· 402 337 static int pckmo_gen_protkey(u32 keytype, u32 subtype, 403 338 u8 *protkey, u32 *protkeylen, u32 *protkeytype) 404 339 { 405 - u8 clrkey[32]; 340 + u8 clrkey[128]; 406 341 int keysize; 407 342 int rc; 408 343 409 - keysize = pkey_keytype_aes_to_size(keytype); 410 - if (!keysize) { 411 - PKEY_DBF_ERR("%s unknown/unsupported keytype %d\n", __func__, 412 - keytype); 344 + switch (keytype) { 345 + case PKEY_KEYTYPE_AES_128: 346 + case PKEY_KEYTYPE_AES_192: 347 + case PKEY_KEYTYPE_AES_256: 348 + keysize = pkey_keytype_aes_to_size(keytype); 349 + break; 350 + case PKEY_KEYTYPE_AES_XTS_128: 351 + keysize = 32; 352 + break; 353 + case PKEY_KEYTYPE_AES_XTS_256: 354 + case PKEY_KEYTYPE_HMAC_512: 355 + keysize = 64; 356 + break; 357 + case PKEY_KEYTYPE_HMAC_1024: 358 + keysize = 128; 359 + break; 360 + default: 361 + PKEY_DBF_ERR("%s unknown/unsupported keytype %d\n", 362 + __func__, keytype); 413 363 return -EINVAL; 414 364 } 415 365 if (subtype != PKEY_TYPE_PROTKEY) {
+132
drivers/s390/crypto/pkey_sysfs.c
··· 99 99 return sizeof(protkeytoken); 100 100 } 101 101 102 + /* 103 + * Sysfs attribute read function for the AES XTS prot key binary attributes. 104 + * The implementation can not deal with partial reads, because a new random 105 + * protected key blob is generated with each read. In case of partial reads 106 + * (i.e. off != 0 or count < key blob size) -EINVAL is returned. 107 + */ 108 + static ssize_t pkey_protkey_aes_xts_attr_read(u32 keytype, char *buf, 109 + loff_t off, size_t count) 110 + { 111 + struct protkeytoken *t = (struct protkeytoken *)buf; 112 + u32 protlen, prottype; 113 + int rc; 114 + 115 + switch (keytype) { 116 + case PKEY_KEYTYPE_AES_XTS_128: 117 + protlen = 64; 118 + break; 119 + case PKEY_KEYTYPE_AES_XTS_256: 120 + protlen = 96; 121 + break; 122 + default: 123 + return -EINVAL; 124 + } 125 + 126 + if (off != 0 || count < sizeof(*t) + protlen) 127 + return -EINVAL; 128 + 129 + memset(t, 0, sizeof(*t) + protlen); 130 + t->type = TOKTYPE_NON_CCA; 131 + t->version = TOKVER_PROTECTED_KEY; 132 + t->keytype = keytype; 133 + 134 + rc = sys_pkey_handler_gen_key(keytype, PKEY_TYPE_PROTKEY, 0, 0, 135 + t->protkey, &protlen, &prottype); 136 + if (rc) 137 + return rc; 138 + 139 + t->len = protlen; 140 + 141 + return sizeof(*t) + protlen; 142 + } 143 + 144 + /* 145 + * Sysfs attribute read function for the HMAC prot key binary attributes. 146 + * The implementation can not deal with partial reads, because a new random 147 + * protected key blob is generated with each read. In case of partial reads 148 + * (i.e. off != 0 or count < key blob size) -EINVAL is returned. 149 + */ 150 + static ssize_t pkey_protkey_hmac_attr_read(u32 keytype, char *buf, 151 + loff_t off, size_t count) 152 + { 153 + struct protkeytoken *t = (struct protkeytoken *)buf; 154 + u32 protlen, prottype; 155 + int rc; 156 + 157 + switch (keytype) { 158 + case PKEY_KEYTYPE_HMAC_512: 159 + protlen = 96; 160 + break; 161 + case PKEY_KEYTYPE_HMAC_1024: 162 + protlen = 160; 163 + break; 164 + default: 165 + return -EINVAL; 166 + } 167 + 168 + if (off != 0 || count < sizeof(*t) + protlen) 169 + return -EINVAL; 170 + 171 + memset(t, 0, sizeof(*t) + protlen); 172 + t->type = TOKTYPE_NON_CCA; 173 + t->version = TOKVER_PROTECTED_KEY; 174 + t->keytype = keytype; 175 + 176 + rc = sys_pkey_handler_gen_key(keytype, PKEY_TYPE_PROTKEY, 0, 0, 177 + t->protkey, &protlen, &prottype); 178 + if (rc) 179 + return rc; 180 + 181 + t->len = protlen; 182 + 183 + return sizeof(*t) + protlen; 184 + } 185 + 102 186 static ssize_t protkey_aes_128_read(struct file *filp, 103 187 struct kobject *kobj, 104 188 struct bin_attribute *attr, ··· 233 149 off, count); 234 150 } 235 151 152 + static ssize_t protkey_aes_xts_128_read(struct file *filp, 153 + struct kobject *kobj, 154 + struct bin_attribute *attr, 155 + char *buf, loff_t off, 156 + size_t count) 157 + { 158 + return pkey_protkey_aes_xts_attr_read(PKEY_KEYTYPE_AES_XTS_128, 159 + buf, off, count); 160 + } 161 + 162 + static ssize_t protkey_aes_xts_256_read(struct file *filp, 163 + struct kobject *kobj, 164 + struct bin_attribute *attr, 165 + char *buf, loff_t off, 166 + size_t count) 167 + { 168 + return pkey_protkey_aes_xts_attr_read(PKEY_KEYTYPE_AES_XTS_256, 169 + buf, off, count); 170 + } 171 + 172 + static ssize_t protkey_hmac_512_read(struct file *filp, 173 + struct kobject *kobj, 174 + struct bin_attribute *attr, 175 + char *buf, loff_t off, 176 + size_t count) 177 + { 178 + return pkey_protkey_hmac_attr_read(PKEY_KEYTYPE_HMAC_512, 179 + buf, off, count); 180 + } 181 + 182 + static ssize_t protkey_hmac_1024_read(struct file *filp, 183 + struct kobject *kobj, 184 + struct bin_attribute *attr, 185 + char *buf, loff_t off, 186 + size_t count) 187 + { 188 + return pkey_protkey_hmac_attr_read(PKEY_KEYTYPE_HMAC_1024, 189 + buf, off, count); 190 + } 191 + 236 192 static BIN_ATTR_RO(protkey_aes_128, sizeof(struct protaeskeytoken)); 237 193 static BIN_ATTR_RO(protkey_aes_192, sizeof(struct protaeskeytoken)); 238 194 static BIN_ATTR_RO(protkey_aes_256, sizeof(struct protaeskeytoken)); 239 195 static BIN_ATTR_RO(protkey_aes_128_xts, 2 * sizeof(struct protaeskeytoken)); 240 196 static BIN_ATTR_RO(protkey_aes_256_xts, 2 * sizeof(struct protaeskeytoken)); 197 + static BIN_ATTR_RO(protkey_aes_xts_128, sizeof(struct protkeytoken) + 64); 198 + static BIN_ATTR_RO(protkey_aes_xts_256, sizeof(struct protkeytoken) + 96); 199 + static BIN_ATTR_RO(protkey_hmac_512, sizeof(struct protkeytoken) + 96); 200 + static BIN_ATTR_RO(protkey_hmac_1024, sizeof(struct protkeytoken) + 160); 241 201 242 202 static struct bin_attribute *protkey_attrs[] = { 243 203 &bin_attr_protkey_aes_128, ··· 289 161 &bin_attr_protkey_aes_256, 290 162 &bin_attr_protkey_aes_128_xts, 291 163 &bin_attr_protkey_aes_256_xts, 164 + &bin_attr_protkey_aes_xts_128, 165 + &bin_attr_protkey_aes_xts_256, 166 + &bin_attr_protkey_hmac_512, 167 + &bin_attr_protkey_hmac_1024, 292 168 NULL 293 169 }; 294 170