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

Configure Feed

Select the types of activity you want to include in your feed.

pseries/plpks: add HCALLs for PowerVM Key Wrapping Module

The hypervisor generated wrapping key is an AES-GCM-256 symmetric key which
is stored in a non-volatile, secure, and encrypted storage called the Power
LPAR Platform KeyStore. It has policy based protections that prevent it
from being read out or exposed to the user.

Implement H_PKS_GEN_KEY, H_PKS_WRAP_OBJECT, and H_PKS_UNWRAP_OBJECT HCALLs
to enable using the PowerVM Key Wrapping Module (PKWM) as a new trust
source for trusted keys. Disallow H_PKS_READ_OBJECT, H_PKS_SIGNED_UPDATE,
and H_PKS_WRITE_OBJECT for objects with the 'wrapping key' policy set.
Capture the availability status for the H_PKS_WRAP_OBJECT interface.

Signed-off-by: Srish Srinivasan <ssrish@linux.ibm.com>
Tested-by: Nayna Jain <nayna@linux.ibm.com>
Reviewed-by: Nayna Jain <nayna@linux.ibm.com>
Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
Link: https://patch.msgid.link/20260127145228.48320-5-ssrish@linux.ibm.com

authored by

Srish Srinivasan and committed by
Madhavan Srinivasan
133aa79e 447eb1d5

+394 -2
+43
Documentation/arch/powerpc/papr_hcalls.rst
··· 300 300 Macro (HTM) function and its data. HTM buffer stores tracing data for functions 301 301 like core instruction, core LLAT and nest. 302 302 303 + **H_PKS_GEN_KEY** 304 + 305 + | Input: authorization, objectlabel, objectlabellen, policy, out, outlen 306 + | Out: *Hypervisor Generated Key, or None when the wrapping key policy is set* 307 + | Return Value: *H_SUCCESS, H_Function, H_State, H_R_State, H_Parameter, H_P2, 308 + H_P3, H_P4, H_P5, H_P6, H_Authority, H_Nomem, H_Busy, H_Resource, 309 + H_Aborted* 310 + 311 + H_PKS_GEN_KEY is used to have the hypervisor generate a new random key. 312 + This key is stored as an object in the Power LPAR Platform KeyStore with 313 + the provided object label. With the wrapping key policy set the key is only 314 + visible to the hypervisor, while the key's label would still be visible to 315 + the user. Generation of wrapping keys is supported only for a key size of 316 + 32 bytes. 317 + 318 + **H_PKS_WRAP_OBJECT** 319 + 320 + | Input: authorization, wrapkeylabel, wrapkeylabellen, objectwrapflags, in, 321 + | inlen, out, outlen, continue-token 322 + | Out: *continue-token, byte size of wrapped object, wrapped object* 323 + | Return Value: *H_SUCCESS, H_Function, H_State, H_R_State, H_Parameter, H_P2, 324 + H_P3, H_P4, H_P5, H_P6, H_P7, H_P8, H_P9, H_Authority, H_Invalid_Key, 325 + H_NOT_FOUND, H_Busy, H_LongBusy, H_Aborted* 326 + 327 + H_PKS_WRAP_OBJECT is used to wrap an object using a wrapping key stored in the 328 + Power LPAR Platform KeyStore and return the wrapped object to the caller. The 329 + caller provides a label to a wrapping key with the 'wrapping key' policy set, 330 + which must have been previously created with H_PKS_GEN_KEY. The provided object 331 + is then encrypted with the wrapping key and additional metadata and the result 332 + is returned to the caller. 333 + 334 + 335 + **H_PKS_UNWRAP_OBJECT** 336 + 337 + | Input: authorization, objectwrapflags, in, inlen, out, outlen, continue-token 338 + | Out: *continue-token, byte size of unwrapped object, unwrapped object* 339 + | Return Value: *H_SUCCESS, H_Function, H_State, H_R_State, H_Parameter, H_P2, 340 + H_P3, H_P4, H_P5, H_P6, H_P7, H_Authority, H_Unsupported, H_Bad_Data, 341 + H_NOT_FOUND, H_Invalid_Key, H_Busy, H_LongBusy, H_Aborted* 342 + 343 + H_PKS_UNWRAP_OBJECT is used to unwrap an object that was previously warapped with 344 + H_PKS_WRAP_OBJECT. 345 + 303 346 References 304 347 ========== 305 348 .. [1] "Power Architecture Platform Reference"
+10
arch/powerpc/include/asm/plpks.h
··· 113 113 int plpks_populate_fdt(void *fdt); 114 114 115 115 int plpks_config_create_softlink(struct kobject *from); 116 + 117 + bool plpks_wrapping_is_supported(void); 118 + 119 + int plpks_gen_wrapping_key(void); 120 + 121 + int plpks_wrap_object(u8 **input_buf, u32 input_len, u16 wrap_flags, 122 + u8 **output_buf, u32 *output_len); 123 + 124 + int plpks_unwrap_object(u8 **input_buf, u32 input_len, 125 + u8 **output_buf, u32 *output_len); 116 126 #else // CONFIG_PSERIES_PLPKS 117 127 static inline bool plpks_is_available(void) { return false; } 118 128 static inline u16 plpks_get_passwordlen(void) { BUILD_BUG(); }
+341 -2
arch/powerpc/platforms/pseries/plpks.c
··· 9 9 10 10 #define pr_fmt(fmt) "plpks: " fmt 11 11 12 + #define PLPKS_WRAPKEY_COMPONENT "PLPKSWR" 13 + #define PLPKS_WRAPKEY_NAME "default-wrapping-key" 14 + 15 + /* 16 + * To 4K align the {input, output} buffers to the {UN}WRAP H_CALLs 17 + */ 18 + #define PLPKS_WRAPPING_BUF_ALIGN 4096 19 + 20 + /* 21 + * To ensure the output buffer's length is at least 1024 bytes greater 22 + * than the input buffer's length during the WRAP H_CALL 23 + */ 24 + #define PLPKS_WRAPPING_BUF_DIFF 1024 25 + 26 + #define PLPKS_WRAP_INTERFACE_BIT 3 27 + #define PLPKS_WRAPPING_KEY_LENGTH 32 28 + 29 + #define WRAPFLAG_BE_BIT_SET(be_bit) \ 30 + BIT_ULL(63 - (be_bit)) 31 + 32 + #define WRAPFLAG_BE_GENMASK(be_bit_hi, be_bit_lo) \ 33 + GENMASK_ULL(63 - (be_bit_hi), 63 - (be_bit_lo)) 34 + 35 + #define WRAPFLAG_BE_FIELD_PREP(be_bit_hi, be_bit_lo, val) \ 36 + FIELD_PREP(WRAPFLAG_BE_GENMASK(be_bit_hi, be_bit_lo), (val)) 37 + 12 38 #include <linux/delay.h> 13 39 #include <linux/errno.h> 14 40 #include <linux/io.h> ··· 45 19 #include <linux/of_fdt.h> 46 20 #include <linux/libfdt.h> 47 21 #include <linux/memblock.h> 22 + #include <linux/bitfield.h> 48 23 #include <asm/hvcall.h> 49 24 #include <asm/machdep.h> 50 25 #include <asm/plpks.h> ··· 66 39 static u32 maxlargeobjectsize; 67 40 static u64 signedupdatealgorithms; 68 41 static u64 wrappingfeatures; 42 + static bool wrapsupport; 69 43 70 44 struct plpks_auth { 71 45 u8 version; ··· 311 283 maxlargeobjectsize = be32_to_cpu(config->maxlargeobjectsize); 312 284 signedupdatealgorithms = be64_to_cpu(config->signedupdatealgorithms); 313 285 wrappingfeatures = be64_to_cpu(config->wrappingfeatures); 286 + wrapsupport = config->flags & PPC_BIT8(PLPKS_WRAP_INTERFACE_BIT); 314 287 315 288 // Validate that the numbers we get back match the requirements of the spec 316 289 if (maxpwsize < 32) { ··· 643 614 if (!(var->policy & PLPKS_SIGNEDUPDATE)) 644 615 return -EINVAL; 645 616 617 + if (var->policy & PLPKS_WRAPPINGKEY) 618 + return -EINVAL; 619 + 646 620 // Signed updates need the component to be NULL. 647 621 if (var->component) 648 622 return -EINVAL; ··· 726 694 return -EINVAL; 727 695 728 696 if (var.policy & PLPKS_SIGNEDUPDATE) 697 + return -EINVAL; 698 + 699 + if (var.policy & PLPKS_WRAPPINGKEY) 729 700 return -EINVAL; 730 701 731 702 auth = construct_auth(PLPKS_OS_OWNER); ··· 825 790 if (var->namelen > PLPKS_MAX_NAME_SIZE) 826 791 return -EINVAL; 827 792 793 + if (var->policy & PLPKS_WRAPPINGKEY) 794 + return -EINVAL; 795 + 828 796 auth = construct_auth(consumer); 829 797 if (IS_ERR(auth)) 830 798 return PTR_ERR(auth); ··· 883 845 } 884 846 885 847 /** 886 - * plpks_read_os_var() - Fetch the data for the specified variable that is 887 - * owned by the OS consumer. 848 + * plpks_wrapping_is_supported() - Get the H_PKS_WRAP_OBJECT interface 849 + * availability status for the LPAR. 850 + * 851 + * Successful execution of the H_PKS_GET_CONFIG HCALL during initialization 852 + * sets bit 3 of the flags variable in the PLPKS config structure if the 853 + * H_PKS_WRAP_OBJECT interface is supported. 854 + * 855 + * Returns: true if the H_PKS_WRAP_OBJECT interface is supported, false if not. 856 + */ 857 + bool plpks_wrapping_is_supported(void) 858 + { 859 + return wrapsupport; 860 + } 861 + 862 + /** 863 + * plpks_gen_wrapping_key() - Generate a new random key with the 'wrapping key' 864 + * policy set. 865 + * 866 + * The H_PKS_GEN_KEY HCALL makes the hypervisor generate a new random key and 867 + * store the key in a PLPKS object with the provided object label. With the 868 + * 'wrapping key' policy set, only the label to the newly generated random key 869 + * would be visible to the user. 870 + * 871 + * Possible reasons for the returned errno values: 872 + * 873 + * -ENXIO if PLPKS is not supported 874 + * -EIO if PLPKS access is blocked due to the LPAR's state 875 + * if PLPKS modification is blocked due to the LPAR's state 876 + * if an error occurred while processing the request 877 + * -EINVAL if invalid authorization parameter 878 + * if invalid object label parameter 879 + * if invalid object label len parameter 880 + * if invalid or unsupported policy declaration 881 + * if invalid output buffer parameter 882 + * if invalid output buffer length parameter 883 + * -EPERM if access is denied 884 + * -ENOMEM if there is inadequate memory to perform this operation 885 + * -EBUSY if unable to handle the request 886 + * -EEXIST if the object label already exists 887 + * 888 + * Returns: On success 0 is returned, a negative errno if not. 889 + */ 890 + int plpks_gen_wrapping_key(void) 891 + { 892 + unsigned long retbuf[PLPAR_HCALL_BUFSIZE] = { 0 }; 893 + struct plpks_auth *auth; 894 + struct label *label; 895 + int rc = 0, pseries_status = 0; 896 + struct plpks_var var = { 897 + .name = PLPKS_WRAPKEY_NAME, 898 + .namelen = strlen(var.name), 899 + .policy = PLPKS_WRAPPINGKEY, 900 + .os = PLPKS_VAR_LINUX, 901 + .component = PLPKS_WRAPKEY_COMPONENT 902 + }; 903 + 904 + auth = construct_auth(PLPKS_OS_OWNER); 905 + if (IS_ERR(auth)) 906 + return PTR_ERR(auth); 907 + 908 + label = construct_label(var.component, var.os, var.name, var.namelen); 909 + if (IS_ERR(label)) { 910 + rc = PTR_ERR(label); 911 + goto out; 912 + } 913 + 914 + rc = plpar_hcall(H_PKS_GEN_KEY, retbuf, 915 + virt_to_phys(auth), virt_to_phys(label), 916 + label->size, var.policy, 917 + NULL, PLPKS_WRAPPING_KEY_LENGTH); 918 + 919 + if (!rc) 920 + rc = plpks_confirm_object_flushed(label, auth); 921 + 922 + pseries_status = rc; 923 + rc = pseries_status_to_err(rc); 924 + 925 + if (rc && rc != -EEXIST) { 926 + pr_err("H_PKS_GEN_KEY failed. pseries_status=%d, rc=%d", 927 + pseries_status, rc); 928 + } else { 929 + rc = 0; 930 + } 931 + 932 + kfree(label); 933 + out: 934 + kfree(auth); 935 + return rc; 936 + } 937 + EXPORT_SYMBOL_GPL(plpks_gen_wrapping_key); 938 + 939 + /** 940 + * plpks_wrap_object() - Wrap an object using the default wrapping key stored in 941 + * the PLPKS. 942 + * @input_buf: buffer containing the data to be wrapped 943 + * @input_len: length of the input buffer 944 + * @wrap_flags: object wrapping flags 945 + * @output_buf: buffer to store the wrapped data 946 + * @output_len: length of the output buffer 947 + * 948 + * The H_PKS_WRAP_OBJECT HCALL wraps an object using a wrapping key stored in 949 + * the PLPKS and returns the wrapped object to the caller. The caller provides a 950 + * label to the wrapping key with the 'wrapping key' policy set that must have 951 + * been previously created with the H_PKS_GEN_KEY HCALL. The provided object is 952 + * then encrypted with the wrapping key and additional metadata and the result 953 + * is returned to the user. The metadata includes the wrapping algorithm and the 954 + * wrapping key name so those parameters are not required during unwrap. 955 + * 956 + * Possible reasons for the returned errno values: 957 + * 958 + * -ENXIO if PLPKS is not supported 959 + * -EIO if PLPKS access is blocked due to the LPAR's state 960 + * if PLPKS modification is blocked due to the LPAR's state 961 + * if an error occurred while processing the request 962 + * -EINVAL if invalid authorization parameter 963 + * if invalid wrapping key label parameter 964 + * if invalid wrapping key label length parameter 965 + * if invalid or unsupported object wrapping flags 966 + * if invalid input buffer parameter 967 + * if invalid input buffer length parameter 968 + * if invalid output buffer parameter 969 + * if invalid output buffer length parameter 970 + * if invalid continue token parameter 971 + * if the wrapping key is not compatible with the wrapping 972 + * algorithm 973 + * -EPERM if access is denied 974 + * -ENOENT if the requested wrapping key was not found 975 + * -EBUSY if unable to handle the request or long running operation 976 + * initiated, retry later. 977 + * 978 + * Returns: On success 0 is returned, a negative errno if not. 979 + */ 980 + int plpks_wrap_object(u8 **input_buf, u32 input_len, u16 wrap_flags, 981 + u8 **output_buf, u32 *output_len) 982 + { 983 + unsigned long retbuf[PLPAR_HCALL9_BUFSIZE] = { 0 }; 984 + struct plpks_auth *auth; 985 + struct label *label; 986 + u64 continuetoken = 0; 987 + u64 objwrapflags = 0; 988 + int rc = 0, pseries_status = 0; 989 + bool sb_audit_or_enforce_bit = wrap_flags & BIT(0); 990 + bool sb_enforce_bit = wrap_flags & BIT(1); 991 + struct plpks_var var = { 992 + .name = PLPKS_WRAPKEY_NAME, 993 + .namelen = strlen(var.name), 994 + .os = PLPKS_VAR_LINUX, 995 + .component = PLPKS_WRAPKEY_COMPONENT 996 + }; 997 + 998 + auth = construct_auth(PLPKS_OS_OWNER); 999 + if (IS_ERR(auth)) 1000 + return PTR_ERR(auth); 1001 + 1002 + label = construct_label(var.component, var.os, var.name, var.namelen); 1003 + if (IS_ERR(label)) { 1004 + rc = PTR_ERR(label); 1005 + goto out; 1006 + } 1007 + 1008 + /* Set the consumer password requirement bit. A must have. */ 1009 + objwrapflags |= WRAPFLAG_BE_BIT_SET(3); 1010 + 1011 + /* Set the wrapping algorithm bit. Just one algorithm option for now */ 1012 + objwrapflags |= WRAPFLAG_BE_FIELD_PREP(60, 63, 0x1); 1013 + 1014 + if (sb_audit_or_enforce_bit & sb_enforce_bit) { 1015 + pr_err("Cannot set both audit/enforce and enforce bits."); 1016 + rc = -EINVAL; 1017 + goto out_free_label; 1018 + } else if (sb_audit_or_enforce_bit) { 1019 + objwrapflags |= WRAPFLAG_BE_BIT_SET(1); 1020 + } else if (sb_enforce_bit) { 1021 + objwrapflags |= WRAPFLAG_BE_BIT_SET(2); 1022 + } 1023 + 1024 + *output_len = input_len + PLPKS_WRAPPING_BUF_DIFF; 1025 + 1026 + *output_buf = kzalloc(ALIGN(*output_len, PLPKS_WRAPPING_BUF_ALIGN), 1027 + GFP_KERNEL); 1028 + if (!(*output_buf)) { 1029 + pr_err("Output buffer allocation failed. Returning -ENOMEM."); 1030 + rc = -ENOMEM; 1031 + goto out_free_label; 1032 + } 1033 + 1034 + do { 1035 + rc = plpar_hcall9(H_PKS_WRAP_OBJECT, retbuf, 1036 + virt_to_phys(auth), virt_to_phys(label), 1037 + label->size, objwrapflags, 1038 + virt_to_phys(*input_buf), input_len, 1039 + virt_to_phys(*output_buf), *output_len, 1040 + continuetoken); 1041 + 1042 + continuetoken = retbuf[0]; 1043 + pseries_status = rc; 1044 + rc = pseries_status_to_err(rc); 1045 + } while (rc == -EBUSY); 1046 + 1047 + if (rc) { 1048 + pr_err("H_PKS_WRAP_OBJECT failed. pseries_status=%d, rc=%d", 1049 + pseries_status, rc); 1050 + kfree(*output_buf); 1051 + *output_buf = NULL; 1052 + } else { 1053 + *output_len = retbuf[1]; 1054 + } 1055 + 1056 + out_free_label: 1057 + kfree(label); 1058 + out: 1059 + kfree(auth); 1060 + return rc; 1061 + } 1062 + EXPORT_SYMBOL_GPL(plpks_wrap_object); 1063 + 1064 + /** 1065 + * plpks_unwrap_object() - Unwrap an object using the default wrapping key 1066 + * stored in the PLPKS. 1067 + * @input_buf: buffer containing the data to be unwrapped 1068 + * @input_len: length of the input buffer 1069 + * @output_buf: buffer to store the unwrapped data 1070 + * @output_len: length of the output buffer 1071 + * 1072 + * The H_PKS_UNWRAP_OBJECT HCALL unwraps an object that was previously wrapped 1073 + * using the H_PKS_WRAP_OBJECT HCALL. 1074 + * 1075 + * Possible reasons for the returned errno values: 1076 + * 1077 + * -ENXIO if PLPKS is not supported 1078 + * -EIO if PLPKS access is blocked due to the LPAR's state 1079 + * if PLPKS modification is blocked due to the LPAR's state 1080 + * if an error occurred while processing the request 1081 + * -EINVAL if invalid authorization parameter 1082 + * if invalid or unsupported object unwrapping flags 1083 + * if invalid input buffer parameter 1084 + * if invalid input buffer length parameter 1085 + * if invalid output buffer parameter 1086 + * if invalid output buffer length parameter 1087 + * if invalid continue token parameter 1088 + * if the wrapping key is not compatible with the wrapping 1089 + * algorithm 1090 + * if the wrapped object's format is not supported 1091 + * if the wrapped object is invalid 1092 + * -EPERM if access is denied 1093 + * -ENOENT if the wrapping key for the provided object was not found 1094 + * -EBUSY if unable to handle the request or long running operation 1095 + * initiated, retry later. 1096 + * 1097 + * Returns: On success 0 is returned, a negative errno if not. 1098 + */ 1099 + int plpks_unwrap_object(u8 **input_buf, u32 input_len, u8 **output_buf, 1100 + u32 *output_len) 1101 + { 1102 + unsigned long retbuf[PLPAR_HCALL9_BUFSIZE] = { 0 }; 1103 + struct plpks_auth *auth; 1104 + u64 continuetoken = 0; 1105 + u64 objwrapflags = 0; 1106 + int rc = 0, pseries_status = 0; 1107 + 1108 + auth = construct_auth(PLPKS_OS_OWNER); 1109 + if (IS_ERR(auth)) 1110 + return PTR_ERR(auth); 1111 + 1112 + *output_len = input_len - PLPKS_WRAPPING_BUF_DIFF; 1113 + *output_buf = kzalloc(ALIGN(*output_len, PLPKS_WRAPPING_BUF_ALIGN), 1114 + GFP_KERNEL); 1115 + if (!(*output_buf)) { 1116 + pr_err("Output buffer allocation failed. Returning -ENOMEM."); 1117 + rc = -ENOMEM; 1118 + goto out; 1119 + } 1120 + 1121 + do { 1122 + rc = plpar_hcall9(H_PKS_UNWRAP_OBJECT, retbuf, 1123 + virt_to_phys(auth), objwrapflags, 1124 + virt_to_phys(*input_buf), input_len, 1125 + virt_to_phys(*output_buf), *output_len, 1126 + continuetoken); 1127 + 1128 + continuetoken = retbuf[0]; 1129 + pseries_status = rc; 1130 + rc = pseries_status_to_err(rc); 1131 + } while (rc == -EBUSY); 1132 + 1133 + if (rc) { 1134 + pr_err("H_PKS_UNWRAP_OBJECT failed. pseries_status=%d, rc=%d", 1135 + pseries_status, rc); 1136 + kfree(*output_buf); 1137 + *output_buf = NULL; 1138 + } else { 1139 + *output_len = retbuf[1]; 1140 + } 1141 + 1142 + out: 1143 + kfree(auth); 1144 + return rc; 1145 + } 1146 + EXPORT_SYMBOL_GPL(plpks_unwrap_object); 1147 + 1148 + /** 1149 + * plpks_read_os_var() - Fetch the data for the specified variable that is owned 1150 + * by the OS consumer. 888 1151 * @var: variable to be read from the PLPKS 889 1152 * 890 1153 * The consumer or the owner of the object is the os kernel. The