0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #define pr_fmt(fmt) "plpks: " fmt
0011
0012 #include <linux/delay.h>
0013 #include <linux/errno.h>
0014 #include <linux/io.h>
0015 #include <linux/printk.h>
0016 #include <linux/slab.h>
0017 #include <linux/string.h>
0018 #include <linux/types.h>
0019 #include <asm/hvcall.h>
0020 #include <asm/machdep.h>
0021
0022 #include "plpks.h"
0023
0024 #define PKS_FW_OWNER 0x1
0025 #define PKS_BOOTLOADER_OWNER 0x2
0026 #define PKS_OS_OWNER 0x3
0027
0028 #define LABEL_VERSION 0
0029 #define MAX_LABEL_ATTR_SIZE 16
0030 #define MAX_NAME_SIZE 239
0031 #define MAX_DATA_SIZE 4000
0032
0033 #define PKS_FLUSH_MAX_TIMEOUT 5000
0034 #define PKS_FLUSH_SLEEP 10
0035 #define PKS_FLUSH_SLEEP_RANGE 400
0036
0037 static u8 *ospassword;
0038 static u16 ospasswordlength;
0039
0040
0041 static u16 maxpwsize;
0042 static u16 maxobjsize;
0043
0044 struct plpks_auth {
0045 u8 version;
0046 u8 consumer;
0047 __be64 rsvd0;
0048 __be32 rsvd1;
0049 __be16 passwordlength;
0050 u8 password[];
0051 } __packed __aligned(16);
0052
0053 struct label_attr {
0054 u8 prefix[8];
0055 u8 version;
0056 u8 os;
0057 u8 length;
0058 u8 reserved[5];
0059 };
0060
0061 struct label {
0062 struct label_attr attr;
0063 u8 name[MAX_NAME_SIZE];
0064 size_t size;
0065 };
0066
0067 static int pseries_status_to_err(int rc)
0068 {
0069 int err;
0070
0071 switch (rc) {
0072 case H_SUCCESS:
0073 err = 0;
0074 break;
0075 case H_FUNCTION:
0076 err = -ENXIO;
0077 break;
0078 case H_P1:
0079 case H_P2:
0080 case H_P3:
0081 case H_P4:
0082 case H_P5:
0083 case H_P6:
0084 err = -EINVAL;
0085 break;
0086 case H_NOT_FOUND:
0087 err = -ENOENT;
0088 break;
0089 case H_BUSY:
0090 err = -EBUSY;
0091 break;
0092 case H_AUTHORITY:
0093 err = -EPERM;
0094 break;
0095 case H_NO_MEM:
0096 err = -ENOMEM;
0097 break;
0098 case H_RESOURCE:
0099 err = -EEXIST;
0100 break;
0101 case H_TOO_BIG:
0102 err = -EFBIG;
0103 break;
0104 case H_STATE:
0105 err = -EIO;
0106 break;
0107 case H_R_STATE:
0108 err = -EIO;
0109 break;
0110 case H_IN_USE:
0111 err = -EEXIST;
0112 break;
0113 case H_ABORTED:
0114 err = -EINTR;
0115 break;
0116 default:
0117 err = -EINVAL;
0118 }
0119
0120 return err;
0121 }
0122
0123 static int plpks_gen_password(void)
0124 {
0125 unsigned long retbuf[PLPAR_HCALL_BUFSIZE] = { 0 };
0126 u8 *password, consumer = PKS_OS_OWNER;
0127 int rc;
0128
0129 password = kzalloc(maxpwsize, GFP_KERNEL);
0130 if (!password)
0131 return -ENOMEM;
0132
0133 rc = plpar_hcall(H_PKS_GEN_PASSWORD, retbuf, consumer, 0,
0134 virt_to_phys(password), maxpwsize);
0135
0136 if (!rc) {
0137 ospasswordlength = maxpwsize;
0138 ospassword = kzalloc(maxpwsize, GFP_KERNEL);
0139 if (!ospassword) {
0140 kfree(password);
0141 return -ENOMEM;
0142 }
0143 memcpy(ospassword, password, ospasswordlength);
0144 } else {
0145 if (rc == H_IN_USE) {
0146 pr_warn("Password is already set for POWER LPAR Platform KeyStore\n");
0147 rc = 0;
0148 } else {
0149 goto out;
0150 }
0151 }
0152 out:
0153 kfree(password);
0154
0155 return pseries_status_to_err(rc);
0156 }
0157
0158 static struct plpks_auth *construct_auth(u8 consumer)
0159 {
0160 struct plpks_auth *auth;
0161
0162 if (consumer > PKS_OS_OWNER)
0163 return ERR_PTR(-EINVAL);
0164
0165 auth = kmalloc(struct_size(auth, password, maxpwsize), GFP_KERNEL);
0166 if (!auth)
0167 return ERR_PTR(-ENOMEM);
0168
0169 auth->version = 1;
0170 auth->consumer = consumer;
0171 auth->rsvd0 = 0;
0172 auth->rsvd1 = 0;
0173
0174 if (consumer == PKS_FW_OWNER || consumer == PKS_BOOTLOADER_OWNER) {
0175 auth->passwordlength = 0;
0176 return auth;
0177 }
0178
0179 memcpy(auth->password, ospassword, ospasswordlength);
0180
0181 auth->passwordlength = cpu_to_be16(ospasswordlength);
0182
0183 return auth;
0184 }
0185
0186
0187
0188
0189
0190 static struct label *construct_label(char *component, u8 varos, u8 *name,
0191 u16 namelen)
0192 {
0193 struct label *label;
0194 size_t slen;
0195
0196 if (!name || namelen > MAX_NAME_SIZE)
0197 return ERR_PTR(-EINVAL);
0198
0199 slen = strlen(component);
0200 if (component && slen > sizeof(label->attr.prefix))
0201 return ERR_PTR(-EINVAL);
0202
0203 label = kzalloc(sizeof(*label), GFP_KERNEL);
0204 if (!label)
0205 return ERR_PTR(-ENOMEM);
0206
0207 if (component)
0208 memcpy(&label->attr.prefix, component, slen);
0209
0210 label->attr.version = LABEL_VERSION;
0211 label->attr.os = varos;
0212 label->attr.length = MAX_LABEL_ATTR_SIZE;
0213 memcpy(&label->name, name, namelen);
0214
0215 label->size = sizeof(struct label_attr) + namelen;
0216
0217 return label;
0218 }
0219
0220 static int _plpks_get_config(void)
0221 {
0222 unsigned long retbuf[PLPAR_HCALL_BUFSIZE] = { 0 };
0223 struct {
0224 u8 version;
0225 u8 flags;
0226 __be32 rsvd0;
0227 __be16 maxpwsize;
0228 __be16 maxobjlabelsize;
0229 __be16 maxobjsize;
0230 __be32 totalsize;
0231 __be32 usedspace;
0232 __be32 supportedpolicies;
0233 __be64 rsvd1;
0234 } __packed config;
0235 size_t size;
0236 int rc;
0237
0238 size = sizeof(config);
0239
0240 rc = plpar_hcall(H_PKS_GET_CONFIG, retbuf, virt_to_phys(&config), size);
0241
0242 if (rc != H_SUCCESS)
0243 return pseries_status_to_err(rc);
0244
0245 maxpwsize = be16_to_cpu(config.maxpwsize);
0246 maxobjsize = be16_to_cpu(config.maxobjsize);
0247
0248 return 0;
0249 }
0250
0251 static int plpks_confirm_object_flushed(struct label *label,
0252 struct plpks_auth *auth)
0253 {
0254 unsigned long retbuf[PLPAR_HCALL_BUFSIZE] = { 0 };
0255 u64 timeout = 0;
0256 u8 status;
0257 int rc;
0258
0259 do {
0260 rc = plpar_hcall(H_PKS_CONFIRM_OBJECT_FLUSHED, retbuf,
0261 virt_to_phys(auth), virt_to_phys(label),
0262 label->size);
0263
0264 status = retbuf[0];
0265 if (rc) {
0266 if (rc == H_NOT_FOUND && status == 1)
0267 rc = 0;
0268 break;
0269 }
0270
0271 if (!rc && status == 1)
0272 break;
0273
0274 usleep_range(PKS_FLUSH_SLEEP,
0275 PKS_FLUSH_SLEEP + PKS_FLUSH_SLEEP_RANGE);
0276 timeout = timeout + PKS_FLUSH_SLEEP;
0277 } while (timeout < PKS_FLUSH_MAX_TIMEOUT);
0278
0279 rc = pseries_status_to_err(rc);
0280
0281 return rc;
0282 }
0283
0284 int plpks_write_var(struct plpks_var var)
0285 {
0286 unsigned long retbuf[PLPAR_HCALL_BUFSIZE] = { 0 };
0287 struct plpks_auth *auth;
0288 struct label *label;
0289 int rc;
0290
0291 if (!var.component || !var.data || var.datalen <= 0 ||
0292 var.namelen > MAX_NAME_SIZE || var.datalen > MAX_DATA_SIZE)
0293 return -EINVAL;
0294
0295 if (var.policy & SIGNEDUPDATE)
0296 return -EINVAL;
0297
0298 auth = construct_auth(PKS_OS_OWNER);
0299 if (IS_ERR(auth))
0300 return PTR_ERR(auth);
0301
0302 label = construct_label(var.component, var.os, var.name, var.namelen);
0303 if (IS_ERR(label)) {
0304 rc = PTR_ERR(label);
0305 goto out;
0306 }
0307
0308 rc = plpar_hcall(H_PKS_WRITE_OBJECT, retbuf, virt_to_phys(auth),
0309 virt_to_phys(label), label->size, var.policy,
0310 virt_to_phys(var.data), var.datalen);
0311
0312 if (!rc)
0313 rc = plpks_confirm_object_flushed(label, auth);
0314
0315 if (rc)
0316 pr_err("Failed to write variable %s for component %s with error %d\n",
0317 var.name, var.component, rc);
0318
0319 rc = pseries_status_to_err(rc);
0320 kfree(label);
0321 out:
0322 kfree(auth);
0323
0324 return rc;
0325 }
0326
0327 int plpks_remove_var(char *component, u8 varos, struct plpks_var_name vname)
0328 {
0329 unsigned long retbuf[PLPAR_HCALL_BUFSIZE] = { 0 };
0330 struct plpks_auth *auth;
0331 struct label *label;
0332 int rc;
0333
0334 if (!component || vname.namelen > MAX_NAME_SIZE)
0335 return -EINVAL;
0336
0337 auth = construct_auth(PKS_OS_OWNER);
0338 if (IS_ERR(auth))
0339 return PTR_ERR(auth);
0340
0341 label = construct_label(component, varos, vname.name, vname.namelen);
0342 if (IS_ERR(label)) {
0343 rc = PTR_ERR(label);
0344 goto out;
0345 }
0346
0347 rc = plpar_hcall(H_PKS_REMOVE_OBJECT, retbuf, virt_to_phys(auth),
0348 virt_to_phys(label), label->size);
0349
0350 if (!rc)
0351 rc = plpks_confirm_object_flushed(label, auth);
0352
0353 if (rc)
0354 pr_err("Failed to remove variable %s for component %s with error %d\n",
0355 vname.name, component, rc);
0356
0357 rc = pseries_status_to_err(rc);
0358 kfree(label);
0359 out:
0360 kfree(auth);
0361
0362 return rc;
0363 }
0364
0365 static int plpks_read_var(u8 consumer, struct plpks_var *var)
0366 {
0367 unsigned long retbuf[PLPAR_HCALL_BUFSIZE] = { 0 };
0368 struct plpks_auth *auth;
0369 struct label *label;
0370 u8 *output;
0371 int rc;
0372
0373 if (var->namelen > MAX_NAME_SIZE)
0374 return -EINVAL;
0375
0376 auth = construct_auth(PKS_OS_OWNER);
0377 if (IS_ERR(auth))
0378 return PTR_ERR(auth);
0379
0380 label = construct_label(var->component, var->os, var->name,
0381 var->namelen);
0382 if (IS_ERR(label)) {
0383 rc = PTR_ERR(label);
0384 goto out_free_auth;
0385 }
0386
0387 output = kzalloc(maxobjsize, GFP_KERNEL);
0388 if (!output) {
0389 rc = -ENOMEM;
0390 goto out_free_label;
0391 }
0392
0393 rc = plpar_hcall(H_PKS_READ_OBJECT, retbuf, virt_to_phys(auth),
0394 virt_to_phys(label), label->size, virt_to_phys(output),
0395 maxobjsize);
0396
0397 if (rc != H_SUCCESS) {
0398 pr_err("Failed to read variable %s for component %s with error %d\n",
0399 var->name, var->component, rc);
0400 rc = pseries_status_to_err(rc);
0401 goto out_free_output;
0402 }
0403
0404 if (var->datalen == 0 || var->datalen > retbuf[0])
0405 var->datalen = retbuf[0];
0406
0407 var->data = kzalloc(var->datalen, GFP_KERNEL);
0408 if (!var->data) {
0409 rc = -ENOMEM;
0410 goto out_free_output;
0411 }
0412 var->policy = retbuf[1];
0413
0414 memcpy(var->data, output, var->datalen);
0415 rc = 0;
0416
0417 out_free_output:
0418 kfree(output);
0419 out_free_label:
0420 kfree(label);
0421 out_free_auth:
0422 kfree(auth);
0423
0424 return rc;
0425 }
0426
0427 int plpks_read_os_var(struct plpks_var *var)
0428 {
0429 return plpks_read_var(PKS_OS_OWNER, var);
0430 }
0431
0432 int plpks_read_fw_var(struct plpks_var *var)
0433 {
0434 return plpks_read_var(PKS_FW_OWNER, var);
0435 }
0436
0437 int plpks_read_bootloader_var(struct plpks_var *var)
0438 {
0439 return plpks_read_var(PKS_BOOTLOADER_OWNER, var);
0440 }
0441
0442 static __init int pseries_plpks_init(void)
0443 {
0444 int rc;
0445
0446 rc = _plpks_get_config();
0447
0448 if (rc) {
0449 pr_err("POWER LPAR Platform KeyStore is not supported or enabled\n");
0450 return rc;
0451 }
0452
0453 rc = plpks_gen_password();
0454 if (rc)
0455 pr_err("Failed setting POWER LPAR Platform KeyStore Password\n");
0456 else
0457 pr_info("POWER LPAR Platform KeyStore initialized successfully\n");
0458
0459 return rc;
0460 }
0461 machine_arch_initcall(pseries, pseries_plpks_init);