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 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 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 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 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 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 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 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 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 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 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