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