diff options
-rw-r--r-- | drivers/scsi/osd/osd_initiator.c | 30 | ||||
-rw-r--r-- | include/scsi/osd_protocol.h | 55 |
2 files changed, 68 insertions, 17 deletions
diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c index e266f803aa96..f61ab84ad20b 100644 --- a/drivers/scsi/osd/osd_initiator.c +++ b/drivers/scsi/osd/osd_initiator.c | |||
@@ -345,9 +345,9 @@ _osd_req_sec_params(struct osd_request *or) | |||
345 | struct osd_cdb *ocdb = &or->cdb; | 345 | struct osd_cdb *ocdb = &or->cdb; |
346 | 346 | ||
347 | if (osd_req_is_ver1(or)) | 347 | if (osd_req_is_ver1(or)) |
348 | return &ocdb->v1.sec_params; | 348 | return (struct osd_security_parameters *)&ocdb->v1.sec_params; |
349 | else | 349 | else |
350 | return &ocdb->v2.sec_params; | 350 | return (struct osd_security_parameters *)&ocdb->v2.sec_params; |
351 | } | 351 | } |
352 | 352 | ||
353 | void osd_dev_init(struct osd_dev *osdd, struct scsi_device *scsi_device) | 353 | void osd_dev_init(struct osd_dev *osdd, struct scsi_device *scsi_device) |
@@ -1209,6 +1209,24 @@ static int _osd_req_finalize_attr_page(struct osd_request *or) | |||
1209 | return ret; | 1209 | return ret; |
1210 | } | 1210 | } |
1211 | 1211 | ||
1212 | static inline void osd_sec_parms_set_out_offset(bool is_v1, | ||
1213 | struct osd_security_parameters *sec_parms, osd_cdb_offset offset) | ||
1214 | { | ||
1215 | if (is_v1) | ||
1216 | sec_parms->v1.data_out_integrity_check_offset = offset; | ||
1217 | else | ||
1218 | sec_parms->v2.data_out_integrity_check_offset = offset; | ||
1219 | } | ||
1220 | |||
1221 | static inline void osd_sec_parms_set_in_offset(bool is_v1, | ||
1222 | struct osd_security_parameters *sec_parms, osd_cdb_offset offset) | ||
1223 | { | ||
1224 | if (is_v1) | ||
1225 | sec_parms->v1.data_in_integrity_check_offset = offset; | ||
1226 | else | ||
1227 | sec_parms->v2.data_in_integrity_check_offset = offset; | ||
1228 | } | ||
1229 | |||
1212 | static int _osd_req_finalize_data_integrity(struct osd_request *or, | 1230 | static int _osd_req_finalize_data_integrity(struct osd_request *or, |
1213 | bool has_in, bool has_out, const u8 *cap_key) | 1231 | bool has_in, bool has_out, const u8 *cap_key) |
1214 | { | 1232 | { |
@@ -1232,8 +1250,8 @@ static int _osd_req_finalize_data_integrity(struct osd_request *or, | |||
1232 | or->out_data_integ.get_attributes_bytes = cpu_to_be64( | 1250 | or->out_data_integ.get_attributes_bytes = cpu_to_be64( |
1233 | or->enc_get_attr.total_bytes); | 1251 | or->enc_get_attr.total_bytes); |
1234 | 1252 | ||
1235 | sec_parms->data_out_integrity_check_offset = | 1253 | osd_sec_parms_set_out_offset(osd_req_is_ver1(or), sec_parms, |
1236 | osd_req_encode_offset(or, or->out.total_bytes, &pad); | 1254 | osd_req_encode_offset(or, or->out.total_bytes, &pad)); |
1237 | 1255 | ||
1238 | ret = _req_append_segment(or, pad, &seg, or->out.last_seg, | 1256 | ret = _req_append_segment(or, pad, &seg, or->out.last_seg, |
1239 | &or->out); | 1257 | &or->out); |
@@ -1253,8 +1271,8 @@ static int _osd_req_finalize_data_integrity(struct osd_request *or, | |||
1253 | }; | 1271 | }; |
1254 | unsigned pad; | 1272 | unsigned pad; |
1255 | 1273 | ||
1256 | sec_parms->data_in_integrity_check_offset = | 1274 | osd_sec_parms_set_in_offset(osd_req_is_ver1(or), sec_parms, |
1257 | osd_req_encode_offset(or, or->in.total_bytes, &pad); | 1275 | osd_req_encode_offset(or, or->in.total_bytes, &pad)); |
1258 | 1276 | ||
1259 | ret = _req_append_segment(or, pad, &seg, or->in.last_seg, | 1277 | ret = _req_append_segment(or, pad, &seg, or->in.last_seg, |
1260 | &or->in); | 1278 | &or->in); |
diff --git a/include/scsi/osd_protocol.h b/include/scsi/osd_protocol.h index fa8343ce3ca2..bbeceeb0e553 100644 --- a/include/scsi/osd_protocol.h +++ b/include/scsi/osd_protocol.h | |||
@@ -33,8 +33,10 @@ enum { | |||
33 | OSD_CAP_LEN = OSDv1_CAP_LEN,/* FIXME: Pete rev-001 sup */ | 33 | OSD_CAP_LEN = OSDv1_CAP_LEN,/* FIXME: Pete rev-001 sup */ |
34 | 34 | ||
35 | OSD_SYSTEMID_LEN = 20, | 35 | OSD_SYSTEMID_LEN = 20, |
36 | OSD_CRYPTO_KEYID_SIZE = 20, | 36 | OSDv1_CRYPTO_KEYID_SIZE = 20, |
37 | /*FIXME: OSDv2_CRYPTO_KEYID_SIZE = 32,*/ | 37 | /*FIXME: OSDv2_CRYPTO_KEYID_SIZE = 32,*/ |
38 | OSDv2_CRYPTO_KEYID_SIZE = 20, | ||
39 | OSD_CRYPTO_KEYID_SIZE = OSDv2_CRYPTO_KEYID_SIZE, | ||
38 | OSD_CRYPTO_SEED_SIZE = 4, | 40 | OSD_CRYPTO_SEED_SIZE = 4, |
39 | OSD_CRYPTO_NONCE_SIZE = 12, | 41 | OSD_CRYPTO_NONCE_SIZE = 12, |
40 | OSD_MAX_SENSE_LEN = 252, /* from SPC-3 */ | 42 | OSD_MAX_SENSE_LEN = 252, /* from SPC-3 */ |
@@ -204,29 +206,40 @@ struct osd_cdb_head { | |||
204 | /*80*/ | 206 | /*80*/ |
205 | 207 | ||
206 | /*160 v1*/ | 208 | /*160 v1*/ |
207 | /*184 v2*/ | 209 | struct osdv1_security_parameters { |
208 | struct osd_security_parameters { | 210 | /*160*/u8 integrity_check_value[OSDv1_CRYPTO_KEYID_SIZE]; |
209 | /*160*/u8 integrity_check_value[OSD_CRYPTO_KEYID_SIZE]; | ||
210 | /*180*/u8 request_nonce[OSD_CRYPTO_NONCE_SIZE]; | 211 | /*180*/u8 request_nonce[OSD_CRYPTO_NONCE_SIZE]; |
211 | /*192*/osd_cdb_offset data_in_integrity_check_offset; | 212 | /*192*/osd_cdb_offset data_in_integrity_check_offset; |
212 | /*196*/osd_cdb_offset data_out_integrity_check_offset; | 213 | /*196*/osd_cdb_offset data_out_integrity_check_offset; |
213 | } __packed; | 214 | } __packed; |
214 | /*200 v1*/ | 215 | /*200 v1*/ |
215 | /*224 v2*/ | ||
216 | 216 | ||
217 | /* FIXME: osdv2_security_parameters */ | 217 | /*184 v2*/ |
218 | struct osdv2_security_parameters { | ||
219 | /*184*/u8 integrity_check_value[OSDv2_CRYPTO_KEYID_SIZE]; | ||
220 | /*216*/u8 request_nonce[OSD_CRYPTO_NONCE_SIZE]; | ||
221 | /*228*/osd_cdb_offset data_in_integrity_check_offset; | ||
222 | /*232*/osd_cdb_offset data_out_integrity_check_offset; | ||
223 | } __packed; | ||
224 | /*236 v2*/ | ||
225 | |||
226 | struct osd_security_parameters { | ||
227 | union { | ||
228 | struct osdv1_security_parameters v1; | ||
229 | struct osdv2_security_parameters v2; | ||
230 | }; | ||
231 | }; | ||
218 | 232 | ||
219 | struct osdv1_cdb { | 233 | struct osdv1_cdb { |
220 | struct osd_cdb_head h; | 234 | struct osd_cdb_head h; |
221 | u8 caps[OSDv1_CAP_LEN]; | 235 | u8 caps[OSDv1_CAP_LEN]; |
222 | struct osd_security_parameters sec_params; | 236 | struct osdv1_security_parameters sec_params; |
223 | } __packed; | 237 | } __packed; |
224 | 238 | ||
225 | struct osdv2_cdb { | 239 | struct osdv2_cdb { |
226 | struct osd_cdb_head h; | 240 | struct osd_cdb_head h; |
227 | u8 caps[OSD_CAP_LEN]; | 241 | u8 caps[OSD_CAP_LEN]; |
228 | struct osd_security_parameters sec_params; | 242 | struct osdv2_security_parameters sec_params; |
229 | /* FIXME: osdv2_security_parameters */ | ||
230 | } __packed; | 243 | } __packed; |
231 | 244 | ||
232 | struct osd_cdb { | 245 | struct osd_cdb { |
@@ -429,15 +442,35 @@ struct osd_data_out_integrity_info { | |||
429 | __be64 data_bytes; | 442 | __be64 data_bytes; |
430 | __be64 set_attributes_bytes; | 443 | __be64 set_attributes_bytes; |
431 | __be64 get_attributes_bytes; | 444 | __be64 get_attributes_bytes; |
432 | __be64 integrity_check_value; | 445 | __u8 integrity_check_value[OSD_CRYPTO_KEYID_SIZE]; |
433 | } __packed; | 446 | } __packed; |
434 | 447 | ||
448 | /* Same osd_data_out_integrity_info is used for OSD2/OSD1. The only difference | ||
449 | * Is the sizeof the structure since in OSD1 the last array is smaller. Use | ||
450 | * below for version independent handling of this structure | ||
451 | */ | ||
452 | static inline int osd_data_out_integrity_info_sizeof(bool is_ver1) | ||
453 | { | ||
454 | return sizeof(struct osd_data_out_integrity_info) - | ||
455 | (is_ver1 * (OSDv2_CRYPTO_KEYID_SIZE - OSDv1_CRYPTO_KEYID_SIZE)); | ||
456 | } | ||
457 | |||
435 | struct osd_data_in_integrity_info { | 458 | struct osd_data_in_integrity_info { |
436 | __be64 data_bytes; | 459 | __be64 data_bytes; |
437 | __be64 retrieved_attributes_bytes; | 460 | __be64 retrieved_attributes_bytes; |
438 | __be64 integrity_check_value; | 461 | __u8 integrity_check_value[OSD_CRYPTO_KEYID_SIZE]; |
439 | } __packed; | 462 | } __packed; |
440 | 463 | ||
464 | /* Same osd_data_in_integrity_info is used for OSD2/OSD1. The only difference | ||
465 | * Is the sizeof the structure since in OSD1 the last array is smaller. Use | ||
466 | * below for version independent handling of this structure | ||
467 | */ | ||
468 | static inline int osd_data_in_integrity_info_sizeof(bool is_ver1) | ||
469 | { | ||
470 | return sizeof(struct osd_data_in_integrity_info) - | ||
471 | (is_ver1 * (OSDv2_CRYPTO_KEYID_SIZE - OSDv1_CRYPTO_KEYID_SIZE)); | ||
472 | } | ||
473 | |||
441 | struct osd_timestamp { | 474 | struct osd_timestamp { |
442 | u8 time[6]; /* number of milliseconds since 1/1/1970 UT (big endian) */ | 475 | u8 time[6]; /* number of milliseconds since 1/1/1970 UT (big endian) */ |
443 | } __packed; | 476 | } __packed; |