1 /* -*- Mode: C; tab-width: 4 -*-
2 *
3 * Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 // ***************************************************************************
19 // CryptoAlg.c:
20 // Interface to DNSSEC cryptographic algorithms. The crypto support itself is
21 // provided by the platform and the functions in this file just provide an
22 // interface to access them in a more generic way.
23 // ***************************************************************************
24
25 #include "mDNSEmbeddedAPI.h"
26 #include "CryptoAlg.h"
27
28 AlgFuncs *DigestAlgFuncs[DIGEST_TYPE_MAX];
29 AlgFuncs *CryptoAlgFuncs[CRYPTO_ALG_MAX];
30 AlgFuncs *EncAlgFuncs[ENC_ALG_MAX];
31
DigestAlgInit(mDNSu8 digestType,AlgFuncs * func)32 mDNSexport mStatus DigestAlgInit(mDNSu8 digestType, AlgFuncs *func)
33 {
34 if (digestType >= DIGEST_TYPE_MAX)
35 {
36 LogMsg("DigestAlgInit: digestType %d exceeds bounds", digestType);
37 return mStatus_BadParamErr;
38 }
39 // As digestTypes may not be consecutive, check for specific digest types
40 // that we support
41 if (digestType != SHA1_DIGEST_TYPE &&
42 digestType != SHA256_DIGEST_TYPE)
43 {
44 LogMsg("DigestAlgInit: digestType %d not supported", digestType);
45 return mStatus_BadParamErr;
46 }
47 DigestAlgFuncs[digestType] = func;
48 return mStatus_NoError;
49 }
50
CryptoAlgInit(mDNSu8 alg,AlgFuncs * func)51 mDNSexport mStatus CryptoAlgInit(mDNSu8 alg, AlgFuncs *func)
52 {
53 if (alg >= CRYPTO_ALG_MAX)
54 {
55 LogMsg("CryptoAlgInit: alg %d exceeds bounds", alg);
56 return mStatus_BadParamErr;
57 }
58 // As algs may not be consecutive, check for specific algorithms
59 // that we support
60 if (alg != CRYPTO_RSA_SHA1 && alg != CRYPTO_RSA_SHA256 && alg != CRYPTO_RSA_SHA512 &&
61 alg != CRYPTO_DSA_NSEC3_SHA1 && alg != CRYPTO_RSA_NSEC3_SHA1)
62 {
63 LogMsg("CryptoAlgInit: alg %d not supported", alg);
64 return mStatus_BadParamErr;
65 }
66
67 CryptoAlgFuncs[alg] = func;
68 return mStatus_NoError;
69 }
70
EncAlgInit(mDNSu8 alg,AlgFuncs * func)71 mDNSexport mStatus EncAlgInit(mDNSu8 alg, AlgFuncs *func)
72 {
73 if (alg >= ENC_ALG_MAX)
74 {
75 LogMsg("EncAlgInit: alg %d exceeds bounds", alg);
76 return mStatus_BadParamErr;
77 }
78
79 // As algs may not be consecutive, check for specific algorithms
80 // that we support
81 if (alg != ENC_BASE32 && alg != ENC_BASE64)
82 {
83 LogMsg("EncAlgInit: alg %d not supported", alg);
84 return mStatus_BadParamErr;
85 }
86
87 EncAlgFuncs[alg] = func;
88 return mStatus_NoError;
89 }
90
AlgCreate(AlgType type,mDNSu8 alg)91 mDNSexport AlgContext *AlgCreate(AlgType type, mDNSu8 alg)
92 {
93 AlgFuncs *func = mDNSNULL;
94 AlgContext *ctx;
95
96 if (type == CRYPTO_ALG)
97 {
98 if (alg >= CRYPTO_ALG_MAX) return mDNSNULL;
99 func = CryptoAlgFuncs[alg];
100 }
101 else if (type == DIGEST_ALG)
102 {
103 if (alg >= DIGEST_TYPE_MAX) return mDNSNULL;
104 func = DigestAlgFuncs[alg];
105 }
106 else if (type == ENC_ALG)
107 {
108 if (alg >= ENC_ALG_MAX) return mDNSNULL;
109 func = EncAlgFuncs[alg];
110 }
111
112 if (!func)
113 {
114 // If there is no support from the platform, this case can happen.
115 LogInfo("AlgCreate: func is NULL");
116 return mDNSNULL;
117 }
118
119 if (func->Create)
120 {
121 mStatus err;
122 ctx = mDNSPlatformMemAllocate(sizeof(AlgContext));
123 if (!ctx) return mDNSNULL;
124 // Create expects ctx->alg to be initialized
125 ctx->alg = alg;
126 err = func->Create(ctx);
127 if (err == mStatus_NoError)
128 {
129 ctx->type = type;
130 return ctx;
131 }
132 mDNSPlatformMemFree(ctx);
133 }
134 return mDNSNULL;
135 }
136
AlgDestroy(AlgContext * ctx)137 mDNSexport mStatus AlgDestroy(AlgContext *ctx)
138 {
139 AlgFuncs *func = mDNSNULL;
140
141 if (ctx->type == CRYPTO_ALG)
142 func = CryptoAlgFuncs[ctx->alg];
143 else if (ctx->type == DIGEST_ALG)
144 func = DigestAlgFuncs[ctx->alg];
145 else if (ctx->type == ENC_ALG)
146 func = EncAlgFuncs[ctx->alg];
147
148 if (!func)
149 {
150 LogMsg("AlgDestroy: ERROR!! func is NULL");
151 mDNSPlatformMemFree(ctx);
152 return mStatus_BadParamErr;
153 }
154
155 if (func->Destroy)
156 func->Destroy(ctx);
157
158 mDNSPlatformMemFree(ctx);
159 return mStatus_NoError;
160 }
161
AlgLength(AlgContext * ctx)162 mDNSexport mDNSu32 AlgLength(AlgContext *ctx)
163 {
164 AlgFuncs *func = mDNSNULL;
165
166 if (ctx->type == CRYPTO_ALG)
167 func = CryptoAlgFuncs[ctx->alg];
168 else if (ctx->type == DIGEST_ALG)
169 func = DigestAlgFuncs[ctx->alg];
170 else if (ctx->type == ENC_ALG)
171 func = EncAlgFuncs[ctx->alg];
172
173 // This should never happen as AlgCreate would have failed
174 if (!func)
175 {
176 LogMsg("AlgLength: ERROR!! func is NULL");
177 return 0;
178 }
179
180 if (func->Length)
181 return (func->Length(ctx));
182 else
183 return 0;
184 }
185
AlgAdd(AlgContext * ctx,const void * data,mDNSu32 len)186 mDNSexport mStatus AlgAdd(AlgContext *ctx, const void *data, mDNSu32 len)
187 {
188 AlgFuncs *func = mDNSNULL;
189
190 if (ctx->type == CRYPTO_ALG)
191 func = CryptoAlgFuncs[ctx->alg];
192 else if (ctx->type == DIGEST_ALG)
193 func = DigestAlgFuncs[ctx->alg];
194 else if (ctx->type == ENC_ALG)
195 func = EncAlgFuncs[ctx->alg];
196
197 // This should never happen as AlgCreate would have failed
198 if (!func)
199 {
200 LogMsg("AlgAdd: ERROR!! func is NULL");
201 return mStatus_BadParamErr;
202 }
203
204 if (func->Add)
205 return (func->Add(ctx, data, len));
206 else
207 return mStatus_BadParamErr;
208 }
209
AlgVerify(AlgContext * ctx,mDNSu8 * key,mDNSu32 keylen,mDNSu8 * signature,mDNSu32 siglen)210 mDNSexport mStatus AlgVerify(AlgContext *ctx, mDNSu8 *key, mDNSu32 keylen, mDNSu8 *signature, mDNSu32 siglen)
211 {
212 AlgFuncs *func = mDNSNULL;
213
214 if (ctx->type == CRYPTO_ALG)
215 func = CryptoAlgFuncs[ctx->alg];
216 else if (ctx->type == DIGEST_ALG)
217 func = DigestAlgFuncs[ctx->alg];
218 else if (ctx->type == ENC_ALG)
219 func = EncAlgFuncs[ctx->alg];
220
221 // This should never happen as AlgCreate would have failed
222 if (!func)
223 {
224 LogMsg("AlgVerify: ERROR!! func is NULL");
225 return mStatus_BadParamErr;
226 }
227
228 if (func->Verify)
229 return (func->Verify(ctx, key, keylen, signature, siglen));
230 else
231 return mStatus_BadParamErr;
232 }
233
AlgEncode(AlgContext * ctx)234 mDNSexport mDNSu8* AlgEncode(AlgContext *ctx)
235 {
236 AlgFuncs *func = mDNSNULL;
237
238 if (ctx->type == CRYPTO_ALG)
239 func = CryptoAlgFuncs[ctx->alg];
240 else if (ctx->type == DIGEST_ALG)
241 func = DigestAlgFuncs[ctx->alg];
242 else if (ctx->type == ENC_ALG)
243 func = EncAlgFuncs[ctx->alg];
244
245 // This should never happen as AlgCreate would have failed
246 if (!func)
247 {
248 LogMsg("AlgEncode: ERROR!! func is NULL");
249 return mDNSNULL;
250 }
251
252 if (func->Encode)
253 return (func->Encode(ctx));
254 else
255 return mDNSNULL;
256 }
257
AlgFinal(AlgContext * ctx,void * data,mDNSu32 len)258 mDNSexport mStatus AlgFinal(AlgContext *ctx, void *data, mDNSu32 len)
259 {
260 AlgFuncs *func = mDNSNULL;
261
262 if (ctx->type == CRYPTO_ALG)
263 func = CryptoAlgFuncs[ctx->alg];
264 else if (ctx->type == DIGEST_ALG)
265 func = DigestAlgFuncs[ctx->alg];
266 else if (ctx->type == ENC_ALG)
267 func = EncAlgFuncs[ctx->alg];
268
269 // This should never happen as AlgCreate would have failed
270 if (!func)
271 {
272 LogMsg("AlgEncode: ERROR!! func is NULL");
273 return mDNSNULL;
274 }
275
276 if (func->Final)
277 return (func->Final(ctx, data, len));
278 else
279 return mStatus_BadParamErr;
280 }
281