]> git.saurik.com Git - apple/xnu.git/blob - osfmk/corecrypto/ccdigest/src/ccdigest_update.c
4df21c38a4aa98919efd91965d4d4e28531dee32
[apple/xnu.git] / osfmk / corecrypto / ccdigest / src / ccdigest_update.c
1 /*
2 * ccdigest_update.c
3 * corecrypto
4 *
5 * Created on 11/30/2010
6 *
7 * Copyright (c) 2010,2011,2014,2015 Apple Inc. All rights reserved.
8 *
9 */
10
11 #include <corecrypto/ccdigest.h>
12 #include <corecrypto/cc_priv.h>
13
14 void ccdigest_update(const struct ccdigest_info *di, ccdigest_ctx_t ctx,
15 size_t len, const void *data) {
16 const char * data_ptr = data;
17 size_t nblocks, nbytes;
18
19 while (len > 0) {
20 if (ccdigest_num(di, ctx) == 0 && len > di->block_size) {
21 //low-end processors are slow on divison
22 if(di->block_size == 1<<6 ){ //sha256
23 nblocks = len >> 6;
24 nbytes = len & 0xFFFFffC0;
25 }else if(di->block_size == 1<<7 ){ //sha512
26 nblocks = len >> 7;
27 nbytes = len & 0xFFFFff80;
28 }else {
29 nblocks = len / di->block_size;
30 nbytes = nblocks * di->block_size;
31 }
32
33 di->compress(ccdigest_state(di, ctx), nblocks, data_ptr);
34 len -= nbytes;
35 data_ptr += nbytes;
36 ccdigest_nbits(di, ctx) += nbytes * 8;
37 } else {
38 size_t n = di->block_size - ccdigest_num(di, ctx);
39 if (len < n)
40 n = len;
41 CC_MEMCPY(ccdigest_data(di, ctx) + ccdigest_num(di, ctx), data_ptr, n);
42 /* typecast: less than block size, will always fit into an int */
43 ccdigest_num(di, ctx) += (unsigned int)n;
44 len -= n;
45 data_ptr += n;
46 if (ccdigest_num(di, ctx) == di->block_size) {
47 di->compress(ccdigest_state(di, ctx), 1, ccdigest_data(di, ctx));
48 ccdigest_nbits(di, ctx) += ccdigest_num(di, ctx) * 8;
49 ccdigest_num(di, ctx) = 0;
50 }
51 }
52 }
53 }