1/*
2 * Copyright (c) 1995 - 2010 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
5 *
6 * Portions Copyright (c) 2010 Apple Inc. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * 3. Neither the name of the Institute nor the names of its contributors
20 *    may be used to endorse or promote products derived from this software
21 *    without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36#include <config.h>
37
38#ifndef HAVE_CCDIGESTCREATE
39
40#define HC_DEPRECATED
41#define HC_DEPRECATED_CRYPTO
42
43#include <sys/types.h>
44#include <stdio.h>
45#include <stdlib.h>
46#include <string.h>
47#include <errno.h>
48
49#include <krb5-types.h>
50
51#if __APPLE_TARGET_EMBEDDED__
52
53#include <CommonCrypto/CommonDigest.h>
54#include <CommonCrypto/CommonCryptor.h>
55#include "CCDGlue.h"
56
57#else
58
59#include "sha.h"
60#include "md5.h"
61#include "md4.h"
62#include "md2.h"
63
64#include "CCDGlue.h"
65
66#endif
67
68struct hc_md_ctx;
69
70typedef int (*hc_cc_md_init)(struct hc_md_ctx *);
71typedef int (*hc_cc_md_update)(struct hc_md_ctx *,const void *, size_t);
72typedef int (*hc_cc_md_final)(void *, struct hc_md_ctx *);
73typedef int (*hc_cc_md_cleanup)(struct hc_md_ctx *);
74
75struct CCDigest_s {
76    int hash_size;
77    int block_size;
78    int ctx_size;
79    hc_cc_md_init init;
80    hc_cc_md_update update;
81    hc_cc_md_final final;
82    hc_cc_md_cleanup cleanup;
83};
84
85#define HC_CC_MD(name, ctxname, outputsize, blocksize)	\
86const struct CCDigest_s hc_kCCDigest##name##_s = {	\
87	outputsize,					\
88	blocksize,					\
89	sizeof(CC_##ctxname##_CTX),			\
90	(hc_cc_md_init)CC_##name##_Init,		\
91	(hc_cc_md_update)CC_##name##_Update,		\
92	(hc_cc_md_final)CC_##name##_Final,		\
93	NULL						\
94    }
95
96HC_CC_MD(MD2, MD2, 16, 16);
97HC_CC_MD(MD4, MD4, 16, 64);
98HC_CC_MD(MD5, MD5, 16, 64);
99HC_CC_MD(SHA1, SHA1, 20, 64);
100HC_CC_MD(SHA256, SHA256, 32, 64);
101#if 0
102HC_CC_MD(SHA384, SHA384, 48, 128);
103HC_CC_MD(SHA512, SHA512, 32, 128);
104#endif
105
106int
107CCDigest(CCDigestAlg algorithm, const void *data, size_t length, void *output)
108{
109    CCDigestRef d = CCDigestCreate(algorithm);
110    if (d == NULL)
111	return ENOMEM;
112    CCDigestUpdate(d, data, length);
113    CCDigestFinal(d, output);
114    CCDigestDestroy(d);
115
116    return 0;
117}
118
119struct CCDigestCtx_s {
120    CCDigestAlg alg;
121};
122
123
124CCDigestRef
125CCDigestCreate(CCDigestAlg alg)
126{
127    CCDigestRef ctx = calloc(1, sizeof(*ctx) + alg->ctx_size);
128    if (ctx == NULL)
129	return NULL;
130
131    ctx->alg = alg;
132    ctx->alg->init((struct hc_md_ctx *)&ctx[1]);
133
134    return ctx;
135
136}
137
138int
139CCDigestUpdate(CCDigestRef ctx, const void *data, size_t length)
140{
141    ctx->alg->update((struct hc_md_ctx *)&ctx[1], data, length);
142    return 0;
143}
144
145int
146CCDigestFinal(CCDigestRef ctx, void *output)
147{
148    ctx->alg->final(output, (struct hc_md_ctx *)&ctx[1]);
149    return 0;
150}
151
152void
153CCDigestDestroy(CCDigestRef ctx)
154{
155    CCDigestAlg alg = ctx->alg;
156    memset(ctx, 0, sizeof(*ctx) + alg->ctx_size);
157    free(ctx);
158}
159
160void
161CCDigestReset(CCDigestRef ctx)
162{
163    ctx->alg->init((struct hc_md_ctx *)&ctx[1]);
164}
165
166size_t
167CCDigestBlockSize(CCDigestRef ctx)
168{
169    return ctx->alg->block_size;
170}
171
172size_t
173CCDigestOutputSize(CCDigestRef ctx)
174{
175    return ctx->alg->hash_size;
176}
177
178#endif /* HAVE_CCDIGESTCREATE */
179