Commit f7b3af64c653c73feb060a9f94f2df9ab4bba4c3
Committed by
Trond Myklebust
1 parent
2d2da60c63
Exists in
master
and in
7 other branches
RPCSEC_GSS: Simplify rpcsec_gss crypto code
Factor out some code that will be shared by privacy crypto routines Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Showing 1 changed file with 77 additions and 29 deletions Side-by-side Diff
net/sunrpc/auth_gss/gss_krb5_crypto.c
... | ... | @@ -139,6 +139,82 @@ |
139 | 139 | sg->length = len; |
140 | 140 | } |
141 | 141 | |
142 | +static int | |
143 | +process_xdr_buf(struct xdr_buf *buf, int offset, int len, | |
144 | + int (*actor)(struct scatterlist *, void *), void *data) | |
145 | +{ | |
146 | + int i, page_len, thislen, page_offset, ret = 0; | |
147 | + struct scatterlist sg[1]; | |
148 | + | |
149 | + if (offset >= buf->head[0].iov_len) { | |
150 | + offset -= buf->head[0].iov_len; | |
151 | + } else { | |
152 | + thislen = buf->head[0].iov_len - offset; | |
153 | + if (thislen > len) | |
154 | + thislen = len; | |
155 | + buf_to_sg(sg, buf->head[0].iov_base + offset, thislen); | |
156 | + ret = actor(sg, data); | |
157 | + if (ret) | |
158 | + goto out; | |
159 | + offset = 0; | |
160 | + len -= thislen; | |
161 | + } | |
162 | + if (len == 0) | |
163 | + goto out; | |
164 | + | |
165 | + if (offset >= buf->page_len) { | |
166 | + offset -= buf->page_len; | |
167 | + } else { | |
168 | + page_len = buf->page_len - offset; | |
169 | + if (page_len > len) | |
170 | + page_len = len; | |
171 | + len -= page_len; | |
172 | + page_offset = (offset + buf->page_base) & (PAGE_CACHE_SIZE - 1); | |
173 | + i = (offset + buf->page_base) >> PAGE_CACHE_SHIFT; | |
174 | + thislen = PAGE_CACHE_SIZE - page_offset; | |
175 | + do { | |
176 | + if (thislen > page_len) | |
177 | + thislen = page_len; | |
178 | + sg->page = buf->pages[i]; | |
179 | + sg->offset = page_offset; | |
180 | + sg->length = thislen; | |
181 | + ret = actor(sg, data); | |
182 | + if (ret) | |
183 | + goto out; | |
184 | + page_len -= thislen; | |
185 | + i++; | |
186 | + page_offset = 0; | |
187 | + thislen = PAGE_CACHE_SIZE; | |
188 | + } while (page_len != 0); | |
189 | + offset = 0; | |
190 | + } | |
191 | + if (len == 0) | |
192 | + goto out; | |
193 | + | |
194 | + if (offset < buf->tail[0].iov_len) { | |
195 | + thislen = buf->tail[0].iov_len - offset; | |
196 | + if (thislen > len) | |
197 | + thislen = len; | |
198 | + buf_to_sg(sg, buf->tail[0].iov_base + offset, thislen); | |
199 | + ret = actor(sg, data); | |
200 | + len -= thislen; | |
201 | + } | |
202 | + if (len != 0) | |
203 | + ret = -EINVAL; | |
204 | +out: | |
205 | + return ret; | |
206 | +} | |
207 | + | |
208 | +static int | |
209 | +checksummer(struct scatterlist *sg, void *data) | |
210 | +{ | |
211 | + struct crypto_tfm *tfm = (struct crypto_tfm *)data; | |
212 | + | |
213 | + crypto_digest_update(tfm, sg, 1); | |
214 | + | |
215 | + return 0; | |
216 | +} | |
217 | + | |
142 | 218 | /* checksum the plaintext data and hdrlen bytes of the token header */ |
143 | 219 | s32 |
144 | 220 | make_checksum(s32 cksumtype, char *header, int hdrlen, struct xdr_buf *body, |
... | ... | @@ -148,8 +224,6 @@ |
148 | 224 | struct crypto_tfm *tfm = NULL; /* XXX add to ctx? */ |
149 | 225 | struct scatterlist sg[1]; |
150 | 226 | u32 code = GSS_S_FAILURE; |
151 | - int len, thislen, offset; | |
152 | - int i; | |
153 | 227 | |
154 | 228 | switch (cksumtype) { |
155 | 229 | case CKSUMTYPE_RSA_MD5: |
... | ... | @@ -169,33 +243,7 @@ |
169 | 243 | crypto_digest_init(tfm); |
170 | 244 | buf_to_sg(sg, header, hdrlen); |
171 | 245 | crypto_digest_update(tfm, sg, 1); |
172 | - if (body->head[0].iov_len) { | |
173 | - buf_to_sg(sg, body->head[0].iov_base, body->head[0].iov_len); | |
174 | - crypto_digest_update(tfm, sg, 1); | |
175 | - } | |
176 | - | |
177 | - len = body->page_len; | |
178 | - if (len != 0) { | |
179 | - offset = body->page_base & (PAGE_CACHE_SIZE - 1); | |
180 | - i = body->page_base >> PAGE_CACHE_SHIFT; | |
181 | - thislen = PAGE_CACHE_SIZE - offset; | |
182 | - do { | |
183 | - if (thislen > len) | |
184 | - thislen = len; | |
185 | - sg->page = body->pages[i]; | |
186 | - sg->offset = offset; | |
187 | - sg->length = thislen; | |
188 | - crypto_digest_update(tfm, sg, 1); | |
189 | - len -= thislen; | |
190 | - i++; | |
191 | - offset = 0; | |
192 | - thislen = PAGE_CACHE_SIZE; | |
193 | - } while(len != 0); | |
194 | - } | |
195 | - if (body->tail[0].iov_len) { | |
196 | - buf_to_sg(sg, body->tail[0].iov_base, body->tail[0].iov_len); | |
197 | - crypto_digest_update(tfm, sg, 1); | |
198 | - } | |
246 | + process_xdr_buf(body, 0, body->len, checksummer, tfm); | |
199 | 247 | crypto_digest_final(tfm, cksum->data); |
200 | 248 | code = 0; |
201 | 249 | out: |