crypto/evp/kdf_meth.c: Add the reset function to the method
[openssl.git] / crypto / evp / mac_lib.c
1 /*
2  * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 #include <string.h>
11 #include <stdarg.h>
12 #include <openssl/evp.h>
13 #include <openssl/err.h>
14 #include <openssl/core.h>
15 #include <openssl/core_names.h>
16 #include <openssl/ossl_typ.h>
17 #include "internal/nelem.h"
18 #include "internal/evp_int.h"
19 #include "internal/provider.h"
20 #include "evp_locl.h"
21
22 EVP_MAC_CTX *EVP_MAC_CTX_new(EVP_MAC *mac)
23 {
24     EVP_MAC_CTX *ctx = OPENSSL_zalloc(sizeof(EVP_MAC_CTX));
25
26     if (ctx == NULL
27         || (ctx->data = mac->newctx(ossl_provider_ctx(mac->prov))) == NULL
28         || !EVP_MAC_up_ref(mac)) {
29         EVPerr(EVP_F_EVP_MAC_CTX_NEW, ERR_R_MALLOC_FAILURE);
30         if (ctx != NULL)
31             mac->freectx(ctx->data);
32         OPENSSL_free(ctx);
33         ctx = NULL;
34     } else {
35         ctx->meth = mac;
36     }
37     return ctx;
38 }
39
40 void EVP_MAC_CTX_free(EVP_MAC_CTX *ctx)
41 {
42     if (ctx != NULL) {
43         ctx->meth->freectx(ctx->data);
44         ctx->data = NULL;
45         /* refcnt-- */
46         EVP_MAC_free(ctx->meth);
47     }
48     OPENSSL_free(ctx);
49 }
50
51 EVP_MAC_CTX *EVP_MAC_CTX_dup(const EVP_MAC_CTX *src)
52 {
53     EVP_MAC_CTX *dst;
54
55     if (src->data == NULL)
56         return NULL;
57
58     dst = OPENSSL_malloc(sizeof(*dst));
59     if (dst == NULL) {
60         EVPerr(EVP_F_EVP_MAC_CTX_DUP, ERR_R_MALLOC_FAILURE);
61         return NULL;
62     }
63
64     *dst = *src;
65     if (!EVP_MAC_up_ref(dst->meth)) {
66         EVPerr(EVP_F_EVP_MAC_CTX_DUP, ERR_R_MALLOC_FAILURE);
67         OPENSSL_free(dst);
68         return NULL;
69     }
70
71     dst->data = src->meth->dupctx(src->data);
72     if (dst->data == NULL) {
73         EVP_MAC_CTX_free(dst);
74         return NULL;
75     }
76
77     return dst;
78 }
79
80 EVP_MAC *EVP_MAC_CTX_mac(EVP_MAC_CTX *ctx)
81 {
82     return ctx->meth;
83 }
84
85 size_t EVP_MAC_size(EVP_MAC_CTX *ctx)
86 {
87     size_t sz = 0;
88
89     if (ctx->data != NULL) {
90         OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
91
92         params[0] = OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_SIZE, &sz);
93         if (ctx->meth->get_ctx_params != NULL) {
94             if (ctx->meth->get_ctx_params(ctx->data, params))
95                 return sz;
96         } else if (ctx->meth->get_params != NULL) {
97             if (ctx->meth->get_params(params))
98                 return sz;
99         }
100     }
101     /*
102      * If the MAC hasn't been initialized yet, or there is no size to get,
103      * we return zero
104      */
105     return 0;
106 }
107
108 int EVP_MAC_init(EVP_MAC_CTX *ctx)
109 {
110     return ctx->meth->init(ctx->data);
111 }
112
113 int EVP_MAC_update(EVP_MAC_CTX *ctx, const unsigned char *data, size_t datalen)
114 {
115     if (datalen == 0)
116         return 1;
117     return ctx->meth->update(ctx->data, data, datalen);
118 }
119
120 int EVP_MAC_final(EVP_MAC_CTX *ctx,
121                   unsigned char *out, size_t *outl, size_t outsize)
122 {
123     int l = EVP_MAC_size(ctx);
124
125     if (l < 0)
126         return 0;
127     if (outl != NULL)
128         *outl = l;
129     if (out == NULL)
130         return 1;
131     return ctx->meth->final(ctx->data, out, outl, outsize);
132 }
133
134 /*
135  * The {get,set}_params functions return 1 if there is no corresponding
136  * function in the implementation.  This is the same as if there was one,
137  * but it didn't recognise any of the given params, i.e. nothing in the
138  * bag of parameters was useful.
139  */
140 int EVP_MAC_get_params(EVP_MAC *mac, OSSL_PARAM params[])
141 {
142     if (mac->get_params != NULL)
143         return mac->get_params(params);
144     return 1;
145 }
146
147 int EVP_MAC_CTX_get_params(EVP_MAC_CTX *ctx, OSSL_PARAM params[])
148 {
149     if (ctx->meth->get_ctx_params != NULL)
150         return ctx->meth->get_ctx_params(ctx->data, params);
151     return 1;
152 }
153
154 int EVP_MAC_CTX_set_params(EVP_MAC_CTX *ctx, const OSSL_PARAM params[])
155 {
156     if (ctx->meth->set_ctx_params != NULL)
157         return ctx->meth->set_ctx_params(ctx->data, params);
158     return 1;
159 }