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

s390/zcrypt: Support CPRB minor version T7

There is a new CPRB minor version T7 to be supported with
this patch. Together with this the functions which extract
the CPRB data from userspace and prepare the AP message do
now check the CPRB minor version and provide some info in
the flag field of the ap message struct for further processing.

The 3 functions doing this job have been renamed to
prep_cca_ap_msg, prep_ep11_ap_msg and prep_rng_ap_msg to
reflect their job better (old was get..fc).

This patch also introduces two new flags to be used internal
with the flag field of the struct ap_message:

AP_MSG_FLAG_USAGE is set when prep_cca_ap_msg or prep_ep11_ap_msg
come to the conclusion that this is a ordinary crypto load CPRB
(which means T2 for CCA CPRBs and no admin bit for EP11 CPRBs).

AP_MSG_FLAG_ADMIN is set when prep_cca_ap_msg or prep_ep11_ap_msg
think, this is an administrative (control) crypto load CPRB
(which means T3, T5, T6 or T7 for CCA CPRBs and admin bit set
for EP11 CPRBs).

Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Reviewed-by: Jürgen Christ <jchrist@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>

authored by

Harald Freudenberger and committed by
Vasily Gorbik
383366b5 a7e701db

+60 -27
+3 -1
drivers/s390/crypto/ap_bus.h
··· 251 251 struct ap_message *); 252 252 }; 253 253 254 - #define AP_MSG_FLAG_SPECIAL 1 /* flag msg as 'special' with NQAP */ 254 + #define AP_MSG_FLAG_SPECIAL 0x0001 /* flag msg as 'special' with NQAP */ 255 + #define AP_MSG_FLAG_USAGE 0x0002 /* CCA, EP11: usage (no admin) msg */ 256 + #define AP_MSG_FLAG_ADMIN 0x0004 /* CCA, EP11: admin (=control) msg */ 255 257 256 258 /** 257 259 * ap_init_message() - Initialize ap_message.
+3 -3
drivers/s390/crypto/zcrypt_api.c
··· 876 876 } 877 877 #endif 878 878 879 - rc = get_cprb_fc(userspace, xcRB, &ap_msg, &func_code, &domain); 879 + rc = prep_cca_ap_msg(userspace, xcRB, &ap_msg, &func_code, &domain); 880 880 if (rc) 881 881 goto out; 882 882 ··· 1058 1058 } 1059 1059 } 1060 1060 1061 - rc = get_ep11cprb_fc(userspace, xcrb, &ap_msg, &func_code); 1061 + rc = prep_ep11_ap_msg(userspace, xcrb, &ap_msg, &func_code); 1062 1062 if (rc) 1063 1063 goto out_free; 1064 1064 ··· 1171 1171 trace_s390_zcrypt_req(buffer, TP_HWRNGCPRB); 1172 1172 1173 1173 ap_init_message(&ap_msg); 1174 - rc = get_rng_fc(&ap_msg, &func_code, &domain); 1174 + rc = prep_rng_ap_msg(&ap_msg, &func_code, &domain); 1175 1175 if (rc) 1176 1176 goto out; 1177 1177
+2 -2
drivers/s390/crypto/zcrypt_msgtype50.c
··· 156 156 unsigned char reserved3[8]; 157 157 } __packed; 158 158 159 - unsigned int get_rsa_modex_fc(struct ica_rsa_modexpo *mex, int *fcode) 159 + int get_rsa_modex_fc(struct ica_rsa_modexpo *mex, int *fcode) 160 160 { 161 161 162 162 if (!mex->inputdatalength) ··· 172 172 return 0; 173 173 } 174 174 175 - unsigned int get_rsa_crt_fc(struct ica_rsa_modexpo_crt *crt, int *fcode) 175 + int get_rsa_crt_fc(struct ica_rsa_modexpo_crt *crt, int *fcode) 176 176 { 177 177 178 178 if (!crt->inputdatalength)
+2 -2
drivers/s390/crypto/zcrypt_msgtype50.h
··· 20 20 21 21 #define MSGTYPE_ADJUSTMENT 0x08 /* type04 extension (not needed in type50) */ 22 22 23 - unsigned int get_rsa_modex_fc(struct ica_rsa_modexpo *, int *); 24 - unsigned int get_rsa_crt_fc(struct ica_rsa_modexpo_crt *, int *); 23 + int get_rsa_modex_fc(struct ica_rsa_modexpo *mex, int *fc); 24 + int get_rsa_crt_fc(struct ica_rsa_modexpo_crt *crt, int *fc); 25 25 26 26 void zcrypt_msgtype50_init(void); 27 27 void zcrypt_msgtype50_exit(void);
+42 -14
drivers/s390/crypto/zcrypt_msgtype6.c
··· 472 472 *fcode = (msg->hdr.function_code[0] << 8) | msg->hdr.function_code[1]; 473 473 *dom = (unsigned short *)&msg->cprbx.domain; 474 474 475 + /* check subfunction, US and AU need special flag with NQAP */ 475 476 if (memcmp(function_code, "US", 2) == 0 476 477 || memcmp(function_code, "AU", 2) == 0) 477 478 ap_msg->flags |= AP_MSG_FLAG_SPECIAL; ··· 481 480 if (ap_msg->fi.flags & AP_FI_FLAG_TOGGLE_SPECIAL) 482 481 ap_msg->flags ^= AP_MSG_FLAG_SPECIAL; 483 482 #endif 483 + 484 + /* check CPRB minor version, set info bits in ap_message flag field */ 485 + switch (*(unsigned short *)(&msg->cprbx.func_id[0])) { 486 + case 0x5432: /* "T2" */ 487 + ap_msg->flags |= AP_MSG_FLAG_USAGE; 488 + break; 489 + case 0x5433: /* "T3" */ 490 + case 0x5435: /* "T5" */ 491 + case 0x5436: /* "T6" */ 492 + case 0x5437: /* "T7" */ 493 + ap_msg->flags |= AP_MSG_FLAG_ADMIN; 494 + break; 495 + default: 496 + ZCRYPT_DBF_DBG("%s unknown CPRB minor version '%c%c'\n", 497 + __func__, msg->cprbx.func_id[0], 498 + msg->cprbx.func_id[1]); 499 + } 484 500 485 501 /* copy data block */ 486 502 if (xcRB->request_data_length && ··· 585 567 if (ap_msg->fi.flags & AP_FI_FLAG_TOGGLE_SPECIAL) 586 568 ap_msg->flags ^= AP_MSG_FLAG_SPECIAL; 587 569 #endif 570 + 571 + /* set info bits in ap_message flag field */ 572 + if (msg->cprbx.flags & 0x80) 573 + ap_msg->flags |= AP_MSG_FLAG_ADMIN; 574 + else 575 + ap_msg->flags |= AP_MSG_FLAG_USAGE; 588 576 589 577 return 0; 590 578 } ··· 1155 1131 } 1156 1132 1157 1133 /* 1158 - * Fetch function code from cprb. 1159 - * Extracting the fc requires to copy the cprb from userspace. 1160 - * So this function allocates memory and needs an ap_msg prepared 1134 + * Prepare a CCA AP msg request. 1135 + * Prepare a CCA AP msg: fetch the required data from userspace, 1136 + * prepare the AP msg, fill some info into the ap_message struct, 1137 + * extract some data from the CPRB and give back to the caller. 1138 + * This function allocates memory and needs an ap_msg prepared 1161 1139 * by the caller with ap_init_message(). Also the caller has to 1162 1140 * make sure ap_release_message() is always called even on failure. 1163 1141 */ 1164 - unsigned int get_cprb_fc(bool userspace, struct ica_xcRB *xcRB, 1165 - struct ap_message *ap_msg, 1166 - unsigned int *func_code, unsigned short **dom) 1142 + int prep_cca_ap_msg(bool userspace, struct ica_xcRB *xcRB, 1143 + struct ap_message *ap_msg, 1144 + unsigned int *func_code, unsigned short **dom) 1167 1145 { 1168 1146 struct response_type resp_type = { 1169 1147 .type = CEXXC_RESPONSE_TYPE_XCRB, ··· 1219 1193 } 1220 1194 1221 1195 /* 1222 - * Fetch function code from ep11 cprb. 1223 - * Extracting the fc requires to copy the ep11 cprb from userspace. 1224 - * So this function allocates memory and needs an ap_msg prepared 1196 + * Prepare an EP11 AP msg request. 1197 + * Prepare an EP11 AP msg: fetch the required data from userspace, 1198 + * prepare the AP msg, fill some info into the ap_message struct, 1199 + * extract some data from the CPRB and give back to the caller. 1200 + * This function allocates memory and needs an ap_msg prepared 1225 1201 * by the caller with ap_init_message(). Also the caller has to 1226 1202 * make sure ap_release_message() is always called even on failure. 1227 1203 */ 1228 - unsigned int get_ep11cprb_fc(bool userspace, struct ep11_urb *xcrb, 1229 - struct ap_message *ap_msg, 1230 - unsigned int *func_code) 1204 + int prep_ep11_ap_msg(bool userspace, struct ep11_urb *xcrb, 1205 + struct ap_message *ap_msg, 1206 + unsigned int *func_code) 1231 1207 { 1232 1208 struct response_type resp_type = { 1233 1209 .type = CEXXC_RESPONSE_TYPE_EP11, ··· 1329 1301 return rc; 1330 1302 } 1331 1303 1332 - unsigned int get_rng_fc(struct ap_message *ap_msg, int *func_code, 1333 - unsigned int *domain) 1304 + int prep_rng_ap_msg(struct ap_message *ap_msg, int *func_code, 1305 + unsigned int *domain) 1334 1306 { 1335 1307 struct response_type resp_type = { 1336 1308 .type = CEXXC_RESPONSE_TYPE_XCRB,
+8 -5
drivers/s390/crypto/zcrypt_msgtype6.h
··· 94 94 unsigned int offset4; /* 0x00000000 */ 95 95 } __packed; 96 96 97 - unsigned int get_cprb_fc(bool userspace, struct ica_xcRB *, struct ap_message *, 98 - unsigned int *, unsigned short **); 99 - unsigned int get_ep11cprb_fc(bool userspace, struct ep11_urb *, struct ap_message *, 100 - unsigned int *); 101 - unsigned int get_rng_fc(struct ap_message *, int *, unsigned int *); 97 + int prep_cca_ap_msg(bool userspace, struct ica_xcRB *xcrb, 98 + struct ap_message *ap_msg, 99 + unsigned int *fc, unsigned short **dom); 100 + int prep_ep11_ap_msg(bool userspace, struct ep11_urb *xcrb, 101 + struct ap_message *ap_msg, 102 + unsigned int *fc); 103 + int prep_rng_ap_msg(struct ap_message *ap_msg, 104 + int *fc, unsigned int *dom); 102 105 103 106 #define LOW 10 104 107 #define MEDIUM 100