diff options
Diffstat (limited to 'drivers/s390/crypto/z90hardware.c')
-rw-r--r-- | drivers/s390/crypto/z90hardware.c | 127 |
1 files changed, 64 insertions, 63 deletions
diff --git a/drivers/s390/crypto/z90hardware.c b/drivers/s390/crypto/z90hardware.c index beb6a5e0da22..c215e0889736 100644 --- a/drivers/s390/crypto/z90hardware.c +++ b/drivers/s390/crypto/z90hardware.c | |||
@@ -32,7 +32,7 @@ | |||
32 | #include "z90crypt.h" | 32 | #include "z90crypt.h" |
33 | #include "z90common.h" | 33 | #include "z90common.h" |
34 | 34 | ||
35 | #define VERSION_Z90HARDWARE_C "$Revision: 1.33 $" | 35 | #define VERSION_Z90HARDWARE_C "$Revision: 1.34 $" |
36 | 36 | ||
37 | char z90hardware_version[] __initdata = | 37 | char z90hardware_version[] __initdata = |
38 | "z90hardware.o (" VERSION_Z90HARDWARE_C "/" | 38 | "z90hardware.o (" VERSION_Z90HARDWARE_C "/" |
@@ -283,48 +283,6 @@ struct type6_msg { | |||
283 | struct CPRB CPRB; | 283 | struct CPRB CPRB; |
284 | }; | 284 | }; |
285 | 285 | ||
286 | union request_msg { | ||
287 | union type4_msg t4msg; | ||
288 | struct type6_msg t6msg; | ||
289 | }; | ||
290 | |||
291 | struct request_msg_ext { | ||
292 | int q_nr; | ||
293 | unsigned char *psmid; | ||
294 | union request_msg reqMsg; | ||
295 | }; | ||
296 | |||
297 | struct type82_hdr { | ||
298 | unsigned char reserved1; | ||
299 | unsigned char type; | ||
300 | unsigned char reserved2[2]; | ||
301 | unsigned char reply_code; | ||
302 | unsigned char reserved3[3]; | ||
303 | }; | ||
304 | |||
305 | #define TYPE82_RSP_CODE 0x82 | ||
306 | |||
307 | #define REPLY_ERROR_MACHINE_FAILURE 0x10 | ||
308 | #define REPLY_ERROR_PREEMPT_FAILURE 0x12 | ||
309 | #define REPLY_ERROR_CHECKPT_FAILURE 0x14 | ||
310 | #define REPLY_ERROR_MESSAGE_TYPE 0x20 | ||
311 | #define REPLY_ERROR_INVALID_COMM_CD 0x21 | ||
312 | #define REPLY_ERROR_INVALID_MSG_LEN 0x23 | ||
313 | #define REPLY_ERROR_RESERVD_FIELD 0x24 | ||
314 | #define REPLY_ERROR_FORMAT_FIELD 0x29 | ||
315 | #define REPLY_ERROR_INVALID_COMMAND 0x30 | ||
316 | #define REPLY_ERROR_MALFORMED_MSG 0x40 | ||
317 | #define REPLY_ERROR_RESERVED_FIELDO 0x50 | ||
318 | #define REPLY_ERROR_WORD_ALIGNMENT 0x60 | ||
319 | #define REPLY_ERROR_MESSAGE_LENGTH 0x80 | ||
320 | #define REPLY_ERROR_OPERAND_INVALID 0x82 | ||
321 | #define REPLY_ERROR_OPERAND_SIZE 0x84 | ||
322 | #define REPLY_ERROR_EVEN_MOD_IN_OPND 0x85 | ||
323 | #define REPLY_ERROR_RESERVED_FIELD 0x88 | ||
324 | #define REPLY_ERROR_TRANSPORT_FAIL 0x90 | ||
325 | #define REPLY_ERROR_PACKET_TRUNCATED 0xA0 | ||
326 | #define REPLY_ERROR_ZERO_BUFFER_LEN 0xB0 | ||
327 | |||
328 | struct type86_hdr { | 286 | struct type86_hdr { |
329 | unsigned char reserved1; | 287 | unsigned char reserved1; |
330 | unsigned char type; | 288 | unsigned char type; |
@@ -338,7 +296,7 @@ struct type86_hdr { | |||
338 | #define TYPE86_FMT2 0x02 | 296 | #define TYPE86_FMT2 0x02 |
339 | 297 | ||
340 | struct type86_fmt2_msg { | 298 | struct type86_fmt2_msg { |
341 | struct type86_hdr hdr; | 299 | struct type86_hdr header; |
342 | unsigned char reserved[4]; | 300 | unsigned char reserved[4]; |
343 | unsigned char apfs[4]; | 301 | unsigned char apfs[4]; |
344 | unsigned int count1; | 302 | unsigned int count1; |
@@ -538,6 +496,8 @@ static struct function_and_rules_block static_pke_function_and_rulesX = { | |||
538 | {'M','R','P',' ',' ',' ',' ',' '} | 496 | {'M','R','P',' ',' ',' ',' ',' '} |
539 | }; | 497 | }; |
540 | 498 | ||
499 | static unsigned char static_PKE_function_code[2] = {0x50, 0x4B}; | ||
500 | |||
541 | struct T6_keyBlock_hdrX { | 501 | struct T6_keyBlock_hdrX { |
542 | unsigned short blen; | 502 | unsigned short blen; |
543 | unsigned short ulen; | 503 | unsigned short ulen; |
@@ -688,9 +648,38 @@ static struct cca_public_sec static_cca_pub_sec = { | |||
688 | #define RESPONSE_CPRB_SIZE 0x000006B8 | 648 | #define RESPONSE_CPRB_SIZE 0x000006B8 |
689 | #define RESPONSE_CPRBX_SIZE 0x00000724 | 649 | #define RESPONSE_CPRBX_SIZE 0x00000724 |
690 | 650 | ||
691 | #define CALLER_HEADER 12 | 651 | struct error_hdr { |
652 | unsigned char reserved1; | ||
653 | unsigned char type; | ||
654 | unsigned char reserved2[2]; | ||
655 | unsigned char reply_code; | ||
656 | unsigned char reserved3[3]; | ||
657 | }; | ||
692 | 658 | ||
693 | static unsigned char static_PKE_function_code[2] = {0x50, 0x4B}; | 659 | #define TYPE82_RSP_CODE 0x82 |
660 | |||
661 | #define REP82_ERROR_MACHINE_FAILURE 0x10 | ||
662 | #define REP82_ERROR_PREEMPT_FAILURE 0x12 | ||
663 | #define REP82_ERROR_CHECKPT_FAILURE 0x14 | ||
664 | #define REP82_ERROR_MESSAGE_TYPE 0x20 | ||
665 | #define REP82_ERROR_INVALID_COMM_CD 0x21 | ||
666 | #define REP82_ERROR_INVALID_MSG_LEN 0x23 | ||
667 | #define REP82_ERROR_RESERVD_FIELD 0x24 | ||
668 | #define REP82_ERROR_FORMAT_FIELD 0x29 | ||
669 | #define REP82_ERROR_INVALID_COMMAND 0x30 | ||
670 | #define REP82_ERROR_MALFORMED_MSG 0x40 | ||
671 | #define REP82_ERROR_RESERVED_FIELDO 0x50 | ||
672 | #define REP82_ERROR_WORD_ALIGNMENT 0x60 | ||
673 | #define REP82_ERROR_MESSAGE_LENGTH 0x80 | ||
674 | #define REP82_ERROR_OPERAND_INVALID 0x82 | ||
675 | #define REP82_ERROR_OPERAND_SIZE 0x84 | ||
676 | #define REP82_ERROR_EVEN_MOD_IN_OPND 0x85 | ||
677 | #define REP82_ERROR_RESERVED_FIELD 0x88 | ||
678 | #define REP82_ERROR_TRANSPORT_FAIL 0x90 | ||
679 | #define REP82_ERROR_PACKET_TRUNCATED 0xA0 | ||
680 | #define REP82_ERROR_ZERO_BUFFER_LEN 0xB0 | ||
681 | |||
682 | #define CALLER_HEADER 12 | ||
694 | 683 | ||
695 | static inline int | 684 | static inline int |
696 | testq(int q_nr, int *q_depth, int *dev_type, struct ap_status_word *stat) | 685 | testq(int q_nr, int *q_depth, int *dev_type, struct ap_status_word *stat) |
@@ -1212,9 +1201,9 @@ send_to_AP(int dev_nr, int cdx, int msg_len, unsigned char *msg_ext) | |||
1212 | struct ap_status_word stat_word; | 1201 | struct ap_status_word stat_word; |
1213 | enum devstat stat; | 1202 | enum devstat stat; |
1214 | int ccode; | 1203 | int ccode; |
1204 | u32 *q_nr_p = (u32 *)msg_ext; | ||
1215 | 1205 | ||
1216 | ((struct request_msg_ext *) msg_ext)->q_nr = | 1206 | *q_nr_p = (dev_nr << SKIP_BITL) + cdx; |
1217 | (dev_nr << SKIP_BITL) + cdx; | ||
1218 | PDEBUG("msg_len passed to sen: %d\n", msg_len); | 1207 | PDEBUG("msg_len passed to sen: %d\n", msg_len); |
1219 | PDEBUG("q number passed to sen: %02x%02x%02x%02x\n", | 1208 | PDEBUG("q number passed to sen: %02x%02x%02x%02x\n", |
1220 | msg_ext[0], msg_ext[1], msg_ext[2], msg_ext[3]); | 1209 | msg_ext[0], msg_ext[1], msg_ext[2], msg_ext[3]); |
@@ -2104,7 +2093,7 @@ convert_response(unsigned char *response, unsigned char *buffer, | |||
2104 | int *respbufflen_p, unsigned char *resp_buff) | 2093 | int *respbufflen_p, unsigned char *resp_buff) |
2105 | { | 2094 | { |
2106 | struct ica_rsa_modexpo *icaMsg_p = (struct ica_rsa_modexpo *) buffer; | 2095 | struct ica_rsa_modexpo *icaMsg_p = (struct ica_rsa_modexpo *) buffer; |
2107 | struct type82_hdr *t82h_p = (struct type82_hdr *) response; | 2096 | struct error_hdr *errh_p = (struct error_hdr *) response; |
2108 | struct type84_hdr *t84h_p = (struct type84_hdr *) response; | 2097 | struct type84_hdr *t84h_p = (struct type84_hdr *) response; |
2109 | struct type86_fmt2_msg *t86m_p = (struct type86_fmt2_msg *) response; | 2098 | struct type86_fmt2_msg *t86m_p = (struct type86_fmt2_msg *) response; |
2110 | int reply_code, service_rc, service_rs, src_l; | 2099 | int reply_code, service_rc, service_rs, src_l; |
@@ -2117,12 +2106,13 @@ convert_response(unsigned char *response, unsigned char *buffer, | |||
2117 | service_rc = 0; | 2106 | service_rc = 0; |
2118 | service_rs = 0; | 2107 | service_rs = 0; |
2119 | src_l = 0; | 2108 | src_l = 0; |
2120 | switch (t82h_p->type) { | 2109 | switch (errh_p->type) { |
2121 | case TYPE82_RSP_CODE: | 2110 | case TYPE82_RSP_CODE: |
2122 | reply_code = t82h_p->reply_code; | 2111 | reply_code = errh_p->reply_code; |
2123 | src_p = (unsigned char *)t82h_p; | 2112 | src_p = (unsigned char *)errh_p; |
2124 | PRINTK("Hardware error: Type 82 Message Header: " | 2113 | PRINTK("Hardware error: Type %02X Message Header: " |
2125 | "%02x%02x%02x%02x%02x%02x%02x%02x\n", | 2114 | "%02x%02x%02x%02x%02x%02x%02x%02x\n", |
2115 | errh_p->type, | ||
2126 | src_p[0], src_p[1], src_p[2], src_p[3], | 2116 | src_p[0], src_p[1], src_p[2], src_p[3], |
2127 | src_p[4], src_p[5], src_p[6], src_p[7]); | 2117 | src_p[4], src_p[5], src_p[6], src_p[7]); |
2128 | break; | 2118 | break; |
@@ -2131,7 +2121,7 @@ convert_response(unsigned char *response, unsigned char *buffer, | |||
2131 | src_p = response + (int)t84h_p->len - src_l; | 2121 | src_p = response + (int)t84h_p->len - src_l; |
2132 | break; | 2122 | break; |
2133 | case TYPE86_RSP_CODE: | 2123 | case TYPE86_RSP_CODE: |
2134 | reply_code = t86m_p->hdr.reply_code; | 2124 | reply_code = t86m_p->header.reply_code; |
2135 | if (reply_code != 0) | 2125 | if (reply_code != 0) |
2136 | break; | 2126 | break; |
2137 | cprb_p = (struct CPRB *) | 2127 | cprb_p = (struct CPRB *) |
@@ -2143,6 +2133,9 @@ convert_response(unsigned char *response, unsigned char *buffer, | |||
2143 | le2toI(cprb_p->ccp_rscode, &service_rs); | 2133 | le2toI(cprb_p->ccp_rscode, &service_rs); |
2144 | if ((service_rc == 8) && (service_rs == 66)) | 2134 | if ((service_rc == 8) && (service_rs == 66)) |
2145 | PDEBUG("Bad block format on PCICC\n"); | 2135 | PDEBUG("Bad block format on PCICC\n"); |
2136 | else if ((service_rc == 8) && (service_rs == 65)) | ||
2137 | PDEBUG("Probably an even modulus on " | ||
2138 | "PCICC\n"); | ||
2146 | else if ((service_rc == 8) && (service_rs == 770)) { | 2139 | else if ((service_rc == 8) && (service_rs == 770)) { |
2147 | PDEBUG("Invalid key length on PCICC\n"); | 2140 | PDEBUG("Invalid key length on PCICC\n"); |
2148 | unset_ext_bitlens(); | 2141 | unset_ext_bitlens(); |
@@ -2155,7 +2148,7 @@ convert_response(unsigned char *response, unsigned char *buffer, | |||
2155 | return REC_USE_PCICA; | 2148 | return REC_USE_PCICA; |
2156 | } | 2149 | } |
2157 | else | 2150 | else |
2158 | PRINTK("service rc/rs: %d/%d\n", | 2151 | PRINTK("service rc/rs (PCICC): %d/%d\n", |
2159 | service_rc, service_rs); | 2152 | service_rc, service_rs); |
2160 | return REC_OPERAND_INV; | 2153 | return REC_OPERAND_INV; |
2161 | } | 2154 | } |
@@ -2169,7 +2162,10 @@ convert_response(unsigned char *response, unsigned char *buffer, | |||
2169 | if (service_rc != 0) { | 2162 | if (service_rc != 0) { |
2170 | service_rs = (int) cprbx_p->ccp_rscode; | 2163 | service_rs = (int) cprbx_p->ccp_rscode; |
2171 | if ((service_rc == 8) && (service_rs == 66)) | 2164 | if ((service_rc == 8) && (service_rs == 66)) |
2172 | PDEBUG("Bad block format on PCXICC\n"); | 2165 | PDEBUG("Bad block format on PCIXCC\n"); |
2166 | else if ((service_rc == 8) && (service_rs == 65)) | ||
2167 | PDEBUG("Probably an even modulus on " | ||
2168 | "PCIXCC\n"); | ||
2173 | else if ((service_rc == 8) && (service_rs == 770)) { | 2169 | else if ((service_rc == 8) && (service_rs == 770)) { |
2174 | PDEBUG("Invalid key length on PCIXCC\n"); | 2170 | PDEBUG("Invalid key length on PCIXCC\n"); |
2175 | unset_ext_bitlens(); | 2171 | unset_ext_bitlens(); |
@@ -2182,7 +2178,7 @@ convert_response(unsigned char *response, unsigned char *buffer, | |||
2182 | return REC_USE_PCICA; | 2178 | return REC_USE_PCICA; |
2183 | } | 2179 | } |
2184 | else | 2180 | else |
2185 | PRINTK("service rc/rs: %d/%d\n", | 2181 | PRINTK("service rc/rs (PCIXCC): %d/%d\n", |
2186 | service_rc, service_rs); | 2182 | service_rc, service_rs); |
2187 | return REC_OPERAND_INV; | 2183 | return REC_OPERAND_INV; |
2188 | } | 2184 | } |
@@ -2195,20 +2191,25 @@ convert_response(unsigned char *response, unsigned char *buffer, | |||
2195 | } | 2191 | } |
2196 | break; | 2192 | break; |
2197 | default: | 2193 | default: |
2194 | src_p = (unsigned char *)errh_p; | ||
2195 | PRINTK("Unrecognized Message Header: " | ||
2196 | "%02x%02x%02x%02x%02x%02x%02x%02x\n", | ||
2197 | src_p[0], src_p[1], src_p[2], src_p[3], | ||
2198 | src_p[4], src_p[5], src_p[6], src_p[7]); | ||
2198 | return REC_BAD_MESSAGE; | 2199 | return REC_BAD_MESSAGE; |
2199 | } | 2200 | } |
2200 | 2201 | ||
2201 | if (reply_code) | 2202 | if (reply_code) |
2202 | switch (reply_code) { | 2203 | switch (reply_code) { |
2203 | case REPLY_ERROR_OPERAND_INVALID: | 2204 | case REP82_ERROR_OPERAND_INVALID: |
2204 | return REC_OPERAND_INV; | 2205 | return REC_OPERAND_INV; |
2205 | case REPLY_ERROR_OPERAND_SIZE: | 2206 | case REP82_ERROR_OPERAND_SIZE: |
2206 | return REC_OPERAND_SIZE; | 2207 | return REC_OPERAND_SIZE; |
2207 | case REPLY_ERROR_EVEN_MOD_IN_OPND: | 2208 | case REP82_ERROR_EVEN_MOD_IN_OPND: |
2208 | return REC_EVEN_MOD; | 2209 | return REC_EVEN_MOD; |
2209 | case REPLY_ERROR_MESSAGE_TYPE: | 2210 | case REP82_ERROR_MESSAGE_TYPE: |
2210 | return WRONG_DEVICE_TYPE; | 2211 | return WRONG_DEVICE_TYPE; |
2211 | case REPLY_ERROR_TRANSPORT_FAIL: | 2212 | case REP82_ERROR_TRANSPORT_FAIL: |
2212 | PRINTKW("Transport failed (APFS = %02X%02X%02X%02X)\n", | 2213 | PRINTKW("Transport failed (APFS = %02X%02X%02X%02X)\n", |
2213 | t86m_p->apfs[0], t86m_p->apfs[1], | 2214 | t86m_p->apfs[0], t86m_p->apfs[1], |
2214 | t86m_p->apfs[2], t86m_p->apfs[3]); | 2215 | t86m_p->apfs[2], t86m_p->apfs[3]); |
@@ -2229,7 +2230,7 @@ convert_response(unsigned char *response, unsigned char *buffer, | |||
2229 | PDEBUG("Length returned = %d\n", src_l); | 2230 | PDEBUG("Length returned = %d\n", src_l); |
2230 | tgt_p = resp_buff + icaMsg_p->outputdatalength - src_l; | 2231 | tgt_p = resp_buff + icaMsg_p->outputdatalength - src_l; |
2231 | memcpy(tgt_p, src_p, src_l); | 2232 | memcpy(tgt_p, src_p, src_l); |
2232 | if ((t82h_p->type == TYPE86_RSP_CODE) && (resp_buff < tgt_p)) { | 2233 | if ((errh_p->type == TYPE86_RSP_CODE) && (resp_buff < tgt_p)) { |
2233 | memset(resp_buff, 0, icaMsg_p->outputdatalength - src_l); | 2234 | memset(resp_buff, 0, icaMsg_p->outputdatalength - src_l); |
2234 | if (pad_msg(resp_buff, icaMsg_p->outputdatalength, src_l)) | 2235 | if (pad_msg(resp_buff, icaMsg_p->outputdatalength, src_l)) |
2235 | return REC_INVALID_PAD; | 2236 | return REC_INVALID_PAD; |