1/*
2 *  ccdigest_update.c
3 *  corecrypto
4 *
5 *  Created by Michael Brouwer on 11/30/10.
6 *  Copyright 2010,2011 Apple Inc. All rights reserved.
7 *
8 */
9
10#include <corecrypto/ccdigest.h>
11#include <corecrypto/cc_priv.h>
12
13void ccdigest_update(const struct ccdigest_info *di, ccdigest_ctx_t ctx,
14                     unsigned long len, const void *data) {
15    char * data_ptr = (char *) data;
16    while (len > 0) {
17        if (ccdigest_num(di, ctx) == 0 && len > di->block_size) {
18            unsigned long nblocks = len / di->block_size;
19            di->compress(ccdigest_state(di, ctx), nblocks, data_ptr);
20            unsigned long nbytes = nblocks * di->block_size;
21            len -= nbytes;
22            data_ptr += nbytes;
23            ccdigest_nbits(di, ctx) += nbytes * 8;
24        } else {
25            unsigned long n = di->block_size - ccdigest_num(di, ctx);
26            if (len < n)
27                n = len;
28            CC_MEMCPY(ccdigest_data(di, ctx) + ccdigest_num(di, ctx), data_ptr, n);
29            /* typecast: less than block size, will always fit into an int */
30            ccdigest_num(di, ctx) += (unsigned int)n;
31            len -= n;
32            data_ptr += n;
33            if (ccdigest_num(di, ctx) == di->block_size) {
34                di->compress(ccdigest_state(di, ctx), 1, ccdigest_data(di, ctx));
35                ccdigest_nbits(di, ctx) += ccdigest_num(di, ctx) * 8;
36                ccdigest_num(di, ctx) = 0;
37            }
38        }
39    }
40}
41