2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
4 * Contact: Krzysztof Jackiewicz <k.jackiewicz@samsung.com>
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License
26 #include <openssl/evp.h>
28 #include <yaca_crypto.h>
29 #include <yaca_digest.h>
30 #include <yaca_error.h>
34 struct yaca_digest_ctx_s {
35 struct yaca_context_s ctx;
40 static struct yaca_digest_ctx_s *get_digest_ctx(const yaca_context_h ctx)
42 if (ctx == YACA_CONTEXT_NULL)
47 return (struct yaca_digest_ctx_s *)ctx;
53 static int get_digest_output_length(const yaca_context_h ctx, size_t input_len, size_t *output_len)
55 struct yaca_digest_ctx_s *c = get_digest_ctx(ctx);
58 return YACA_ERROR_INVALID_PARAMETER;
60 int md_size = EVP_MD_CTX_size(c->mdctx);
62 return YACA_ERROR_INTERNAL;
64 *output_len = md_size;
66 return YACA_ERROR_NONE;
69 static void destroy_digest_context(yaca_context_h ctx)
71 struct yaca_digest_ctx_s *c = get_digest_ctx(ctx);
76 EVP_MD_CTX_destroy(c->mdctx);
80 int digest_get_algorithm(yaca_digest_algorithm_e algo, const EVP_MD **md)
82 int ret = YACA_ERROR_NONE;
85 return YACA_ERROR_INVALID_PARAMETER;
93 case YACA_DIGEST_SHA1:
96 case YACA_DIGEST_SHA224:
99 case YACA_DIGEST_SHA256:
102 case YACA_DIGEST_SHA384:
105 case YACA_DIGEST_SHA512:
109 ret = YACA_ERROR_INVALID_PARAMETER;
113 if (ret == YACA_ERROR_NONE && *md == NULL) {
114 ret = YACA_ERROR_INTERNAL;
121 API int yaca_digest_initialize(yaca_context_h *ctx, yaca_digest_algorithm_e algo)
124 struct yaca_digest_ctx_s *nc = NULL;
128 return YACA_ERROR_INVALID_PARAMETER;
130 ret = yaca_zalloc(sizeof(struct yaca_digest_ctx_s), (void**)&nc);
131 if (ret != YACA_ERROR_NONE)
134 nc->ctx.type = YACA_CTX_DIGEST;
135 nc->ctx.ctx_destroy = destroy_digest_context;
136 nc->ctx.get_output_length = get_digest_output_length;
138 ret = digest_get_algorithm(algo, &md);
139 if (ret != YACA_ERROR_NONE)
142 nc->mdctx = EVP_MD_CTX_create();
143 if (nc->mdctx == NULL) {
144 ret = YACA_ERROR_INTERNAL;
149 ret = EVP_DigestInit(nc->mdctx, md);
151 ret = YACA_ERROR_INTERNAL;
156 *ctx = (yaca_context_h)nc;
158 ret = YACA_ERROR_NONE;
161 yaca_context_destroy((yaca_context_h)nc);
166 API int yaca_digest_update(yaca_context_h ctx, const char *data, size_t data_len)
168 struct yaca_digest_ctx_s *c = get_digest_ctx(ctx);
171 if (c == NULL || data == NULL || data_len == 0)
172 return YACA_ERROR_INVALID_PARAMETER;
174 ret = EVP_DigestUpdate(c->mdctx, data, data_len);
176 ret = YACA_ERROR_INTERNAL;
181 return YACA_ERROR_NONE;
184 API int yaca_digest_finalize(yaca_context_h ctx, char *digest, size_t *digest_len)
186 struct yaca_digest_ctx_s *c = get_digest_ctx(ctx);
190 if (c == NULL || digest == NULL || digest_len == NULL)
191 return YACA_ERROR_INVALID_PARAMETER;
193 if (*digest_len == 0 || *digest_len > UINT_MAX) /* DigestFinal accepts UINT */
194 return YACA_ERROR_INVALID_PARAMETER;
196 ret = EVP_DigestFinal_ex(c->mdctx, (unsigned char*)digest, &len);
198 ret = YACA_ERROR_INTERNAL;
205 return YACA_ERROR_NONE;