summaryrefslogtreecommitdiffstats
path: root/mDNSResponder/mDNSCore/CryptoAlg.c
diff options
context:
space:
mode:
Diffstat (limited to 'mDNSResponder/mDNSCore/CryptoAlg.c')
-rw-r--r--mDNSResponder/mDNSCore/CryptoAlg.c280
1 files changed, 280 insertions, 0 deletions
diff --git a/mDNSResponder/mDNSCore/CryptoAlg.c b/mDNSResponder/mDNSCore/CryptoAlg.c
new file mode 100644
index 00000000..38533fc8
--- /dev/null
+++ b/mDNSResponder/mDNSCore/CryptoAlg.c
@@ -0,0 +1,280 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// ***************************************************************************
+// CryptoAlg.c:
+// Interface to DNSSEC cryptographic algorithms. The crypto support itself is
+// provided by the platform and the functions in this file just provide an
+// interface to access them in a more generic way.
+// ***************************************************************************
+
+#include "mDNSEmbeddedAPI.h"
+#include "CryptoAlg.h"
+
+AlgFuncs *DigestAlgFuncs[DIGEST_TYPE_MAX];
+AlgFuncs *CryptoAlgFuncs[CRYPTO_ALG_MAX];
+AlgFuncs *EncAlgFuncs[ENC_ALG_MAX];
+
+mDNSexport mStatus DigestAlgInit(mDNSu8 digestType, AlgFuncs *func)
+{
+ if (digestType >= DIGEST_TYPE_MAX)
+ {
+ LogMsg("DigestAlgInit: digestType %d exceeds bounds", digestType);
+ return mStatus_BadParamErr;
+ }
+ // As digestTypes may not be consecutive, check for specific digest types
+ // that we support
+ if (digestType != SHA1_DIGEST_TYPE &&
+ digestType != SHA256_DIGEST_TYPE)
+ {
+ LogMsg("DigestAlgInit: digestType %d not supported", digestType);
+ return mStatus_BadParamErr;
+ }
+ DigestAlgFuncs[digestType] = func;
+ return mStatus_NoError;
+}
+
+mDNSexport mStatus CryptoAlgInit(mDNSu8 alg, AlgFuncs *func)
+{
+ if (alg >= CRYPTO_ALG_MAX)
+ {
+ LogMsg("CryptoAlgInit: alg %d exceeds bounds", alg);
+ return mStatus_BadParamErr;
+ }
+ // As algs may not be consecutive, check for specific algorithms
+ // that we support
+ if (alg != CRYPTO_RSA_SHA1 && alg != CRYPTO_RSA_SHA256 && alg != CRYPTO_RSA_SHA512 &&
+ alg != CRYPTO_DSA_NSEC3_SHA1 && alg != CRYPTO_RSA_NSEC3_SHA1)
+ {
+ LogMsg("CryptoAlgInit: alg %d not supported", alg);
+ return mStatus_BadParamErr;
+ }
+
+ CryptoAlgFuncs[alg] = func;
+ return mStatus_NoError;
+}
+
+mDNSexport mStatus EncAlgInit(mDNSu8 alg, AlgFuncs *func)
+{
+ if (alg >= ENC_ALG_MAX)
+ {
+ LogMsg("EncAlgInit: alg %d exceeds bounds", alg);
+ return mStatus_BadParamErr;
+ }
+
+ // As algs may not be consecutive, check for specific algorithms
+ // that we support
+ if (alg != ENC_BASE32 && alg != ENC_BASE64)
+ {
+ LogMsg("EncAlgInit: alg %d not supported", alg);
+ return mStatus_BadParamErr;
+ }
+
+ EncAlgFuncs[alg] = func;
+ return mStatus_NoError;
+}
+
+mDNSexport AlgContext *AlgCreate(AlgType type, mDNSu8 alg)
+{
+ AlgFuncs *func = mDNSNULL;
+ AlgContext *ctx;
+
+ if (type == CRYPTO_ALG)
+ {
+ if (alg >= CRYPTO_ALG_MAX) return mDNSNULL;
+ func = CryptoAlgFuncs[alg];
+ }
+ else if (type == DIGEST_ALG)
+ {
+ if (alg >= DIGEST_TYPE_MAX) return mDNSNULL;
+ func = DigestAlgFuncs[alg];
+ }
+ else if (type == ENC_ALG)
+ {
+ if (alg >= ENC_ALG_MAX) return mDNSNULL;
+ func = EncAlgFuncs[alg];
+ }
+
+ if (!func)
+ {
+ // If there is no support from the platform, this case can happen.
+ LogInfo("AlgCreate: func is NULL");
+ return mDNSNULL;
+ }
+
+ if (func->Create)
+ {
+ mStatus err;
+ ctx = mDNSPlatformMemAllocate(sizeof(AlgContext));
+ if (!ctx) return mDNSNULL;
+ // Create expects ctx->alg to be initialized
+ ctx->alg = alg;
+ err = func->Create(ctx);
+ if (err == mStatus_NoError)
+ {
+ ctx->type = type;
+ return ctx;
+ }
+ mDNSPlatformMemFree(ctx);
+ }
+ return mDNSNULL;
+}
+
+mDNSexport mStatus AlgDestroy(AlgContext *ctx)
+{
+ AlgFuncs *func = mDNSNULL;
+
+ if (ctx->type == CRYPTO_ALG)
+ func = CryptoAlgFuncs[ctx->alg];
+ else if (ctx->type == DIGEST_ALG)
+ func = DigestAlgFuncs[ctx->alg];
+ else if (ctx->type == ENC_ALG)
+ func = EncAlgFuncs[ctx->alg];
+
+ if (!func)
+ {
+ LogMsg("AlgDestroy: ERROR!! func is NULL");
+ mDNSPlatformMemFree(ctx);
+ return mStatus_BadParamErr;
+ }
+
+ if (func->Destroy)
+ func->Destroy(ctx);
+
+ mDNSPlatformMemFree(ctx);
+ return mStatus_NoError;
+}
+
+mDNSexport mDNSu32 AlgLength(AlgContext *ctx)
+{
+ AlgFuncs *func = mDNSNULL;
+
+ if (ctx->type == CRYPTO_ALG)
+ func = CryptoAlgFuncs[ctx->alg];
+ else if (ctx->type == DIGEST_ALG)
+ func = DigestAlgFuncs[ctx->alg];
+ else if (ctx->type == ENC_ALG)
+ func = EncAlgFuncs[ctx->alg];
+
+ // This should never happen as AlgCreate would have failed
+ if (!func)
+ {
+ LogMsg("AlgLength: ERROR!! func is NULL");
+ return 0;
+ }
+
+ if (func->Length)
+ return (func->Length(ctx));
+ else
+ return 0;
+}
+
+mDNSexport mStatus AlgAdd(AlgContext *ctx, const void *data, mDNSu32 len)
+{
+ AlgFuncs *func = mDNSNULL;
+
+ if (ctx->type == CRYPTO_ALG)
+ func = CryptoAlgFuncs[ctx->alg];
+ else if (ctx->type == DIGEST_ALG)
+ func = DigestAlgFuncs[ctx->alg];
+ else if (ctx->type == ENC_ALG)
+ func = EncAlgFuncs[ctx->alg];
+
+ // This should never happen as AlgCreate would have failed
+ if (!func)
+ {
+ LogMsg("AlgAdd: ERROR!! func is NULL");
+ return mStatus_BadParamErr;
+ }
+
+ if (func->Add)
+ return (func->Add(ctx, data, len));
+ else
+ return mStatus_BadParamErr;
+}
+
+mDNSexport mStatus AlgVerify(AlgContext *ctx, mDNSu8 *key, mDNSu32 keylen, mDNSu8 *signature, mDNSu32 siglen)
+{
+ AlgFuncs *func = mDNSNULL;
+
+ if (ctx->type == CRYPTO_ALG)
+ func = CryptoAlgFuncs[ctx->alg];
+ else if (ctx->type == DIGEST_ALG)
+ func = DigestAlgFuncs[ctx->alg];
+ else if (ctx->type == ENC_ALG)
+ func = EncAlgFuncs[ctx->alg];
+
+ // This should never happen as AlgCreate would have failed
+ if (!func)
+ {
+ LogMsg("AlgVerify: ERROR!! func is NULL");
+ return mStatus_BadParamErr;
+ }
+
+ if (func->Verify)
+ return (func->Verify(ctx, key, keylen, signature, siglen));
+ else
+ return mStatus_BadParamErr;
+}
+
+mDNSexport mDNSu8* AlgEncode(AlgContext *ctx)
+{
+ AlgFuncs *func = mDNSNULL;
+
+ if (ctx->type == CRYPTO_ALG)
+ func = CryptoAlgFuncs[ctx->alg];
+ else if (ctx->type == DIGEST_ALG)
+ func = DigestAlgFuncs[ctx->alg];
+ else if (ctx->type == ENC_ALG)
+ func = EncAlgFuncs[ctx->alg];
+
+ // This should never happen as AlgCreate would have failed
+ if (!func)
+ {
+ LogMsg("AlgEncode: ERROR!! func is NULL");
+ return mDNSNULL;
+ }
+
+ if (func->Encode)
+ return (func->Encode(ctx));
+ else
+ return mDNSNULL;
+}
+
+mDNSexport mStatus AlgFinal(AlgContext *ctx, void *data, mDNSu32 len)
+{
+ AlgFuncs *func = mDNSNULL;
+
+ if (ctx->type == CRYPTO_ALG)
+ func = CryptoAlgFuncs[ctx->alg];
+ else if (ctx->type == DIGEST_ALG)
+ func = DigestAlgFuncs[ctx->alg];
+ else if (ctx->type == ENC_ALG)
+ func = EncAlgFuncs[ctx->alg];
+
+ // This should never happen as AlgCreate would have failed
+ if (!func)
+ {
+ LogMsg("AlgEncode: ERROR!! func is NULL");
+ return mDNSNULL;
+ }
+
+ if (func->Final)
+ return (func->Final(ctx, data, len));
+ else
+ return mStatus_BadParamErr;
+}