| 1071 | } |
| 1072 | |
| 1073 | static int __must_check |
| 1074 | ccp_sha(struct ccp_queue *qp, enum sha_version version, struct sglist *sgl_src, |
| 1075 | struct sglist *sgl_dst, const struct ccp_completion_ctx *cctx) |
| 1076 | { |
| 1077 | const struct SHA_Defn *defn; |
| 1078 | struct sglist_seg *seg; |
| 1079 | size_t i, msgsize, remaining, nb; |
| 1080 | uint32_t lsbaddr; |
| 1081 | int error; |
| 1082 | |
| 1083 | for (i = 0; i < nitems(SHA_definitions); i++) |
| 1084 | if (SHA_definitions[i].version == version) |
| 1085 | break; |
| 1086 | if (i == nitems(SHA_definitions)) |
| 1087 | return (EINVAL); |
| 1088 | defn = &SHA_definitions[i]; |
| 1089 | |
| 1090 | /* XXX validate input ??? */ |
| 1091 | |
| 1092 | /* Load initial SHA state into LSB */ |
| 1093 | /* XXX ensure H_vectors don't span page boundaries */ |
| 1094 | error = ccp_passthrough(qp, ccp_queue_lsb_address(qp, LSB_ENTRY_SHA), |
| 1095 | CCP_MEMTYPE_SB, pmap_kextract((vm_offset_t)defn->H_vectors), |
| 1096 | CCP_MEMTYPE_SYSTEM, roundup2(defn->H_size, LSB_ENTRY_SIZE), |
| 1097 | CCP_PASSTHRU_BYTESWAP_NOOP, CCP_PASSTHRU_BITWISE_NOOP, false, |
| 1098 | NULL); |
| 1099 | if (error != 0) |
| 1100 | return (error); |
| 1101 | |
| 1102 | /* Execute series of SHA updates on correctly sized buffers */ |
| 1103 | msgsize = 0; |
| 1104 | for (i = 0; i < sgl_src->sg_nseg; i++) { |
| 1105 | seg = &sgl_src->sg_segs[i]; |
| 1106 | msgsize += seg->ss_len; |
| 1107 | error = ccp_sha_single_desc(qp, defn, seg->ss_paddr, |
| 1108 | seg->ss_len, i == 0, i == sgl_src->sg_nseg - 1, |
| 1109 | msgsize << 3); |
| 1110 | if (error != 0) |
| 1111 | return (error); |
| 1112 | } |
| 1113 | |
| 1114 | /* Copy result out to sgl_dst */ |
| 1115 | remaining = roundup2(defn->H_size, LSB_ENTRY_SIZE); |
| 1116 | lsbaddr = ccp_queue_lsb_address(qp, LSB_ENTRY_SHA); |
| 1117 | for (i = 0; i < sgl_dst->sg_nseg; i++) { |
| 1118 | seg = &sgl_dst->sg_segs[i]; |
| 1119 | /* crp lengths are int, so 32-bit min() is ok. */ |
| 1120 | nb = min(remaining, seg->ss_len); |
| 1121 | |
| 1122 | error = ccp_passthrough(qp, seg->ss_paddr, CCP_MEMTYPE_SYSTEM, |
| 1123 | lsbaddr, CCP_MEMTYPE_SB, nb, CCP_PASSTHRU_BYTESWAP_NOOP, |
| 1124 | CCP_PASSTHRU_BITWISE_NOOP, |
| 1125 | (cctx != NULL) ? (nb == remaining) : false, |
| 1126 | (nb == remaining) ? cctx : NULL); |
| 1127 | if (error != 0) |
| 1128 | return (error); |
| 1129 | |
| 1130 | remaining -= nb; |
no test coverage detected