xref: /freebsd-src/crypto/openssl/crypto/evp/kdf_lib.c (revision b077aed33b7b6aefca7b17ddb250cf521f938613)
1*b077aed3SPierre Pronchery /*
2*b077aed3SPierre Pronchery  * Copyright 2018-2022 The OpenSSL Project Authors. All Rights Reserved.
3*b077aed3SPierre Pronchery  * Copyright (c) 2018-2019, Oracle and/or its affiliates.  All rights reserved.
4*b077aed3SPierre Pronchery  *
5*b077aed3SPierre Pronchery  * Licensed under the Apache License 2.0 (the "License").  You may not use
6*b077aed3SPierre Pronchery  * this file except in compliance with the License.  You can obtain a copy
7*b077aed3SPierre Pronchery  * in the file LICENSE in the source distribution or at
8*b077aed3SPierre Pronchery  * https://www.openssl.org/source/license.html
9*b077aed3SPierre Pronchery  */
10*b077aed3SPierre Pronchery 
11*b077aed3SPierre Pronchery #include <stdio.h>
12*b077aed3SPierre Pronchery #include <stdlib.h>
13*b077aed3SPierre Pronchery #include "internal/cryptlib.h"
14*b077aed3SPierre Pronchery #include <openssl/evp.h>
15*b077aed3SPierre Pronchery #include <openssl/kdf.h>
16*b077aed3SPierre Pronchery #include <openssl/core.h>
17*b077aed3SPierre Pronchery #include <openssl/core_names.h>
18*b077aed3SPierre Pronchery #include "crypto/evp.h"
19*b077aed3SPierre Pronchery #include "internal/numbers.h"
20*b077aed3SPierre Pronchery #include "internal/provider.h"
21*b077aed3SPierre Pronchery #include "evp_local.h"
22*b077aed3SPierre Pronchery 
EVP_KDF_CTX_new(EVP_KDF * kdf)23*b077aed3SPierre Pronchery EVP_KDF_CTX *EVP_KDF_CTX_new(EVP_KDF *kdf)
24*b077aed3SPierre Pronchery {
25*b077aed3SPierre Pronchery     EVP_KDF_CTX *ctx = NULL;
26*b077aed3SPierre Pronchery 
27*b077aed3SPierre Pronchery     if (kdf == NULL)
28*b077aed3SPierre Pronchery         return NULL;
29*b077aed3SPierre Pronchery 
30*b077aed3SPierre Pronchery     ctx = OPENSSL_zalloc(sizeof(EVP_KDF_CTX));
31*b077aed3SPierre Pronchery     if (ctx == NULL
32*b077aed3SPierre Pronchery         || (ctx->algctx = kdf->newctx(ossl_provider_ctx(kdf->prov))) == NULL
33*b077aed3SPierre Pronchery         || !EVP_KDF_up_ref(kdf)) {
34*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
35*b077aed3SPierre Pronchery         if (ctx != NULL)
36*b077aed3SPierre Pronchery             kdf->freectx(ctx->algctx);
37*b077aed3SPierre Pronchery         OPENSSL_free(ctx);
38*b077aed3SPierre Pronchery         ctx = NULL;
39*b077aed3SPierre Pronchery     } else {
40*b077aed3SPierre Pronchery         ctx->meth = kdf;
41*b077aed3SPierre Pronchery     }
42*b077aed3SPierre Pronchery     return ctx;
43*b077aed3SPierre Pronchery }
44*b077aed3SPierre Pronchery 
EVP_KDF_CTX_free(EVP_KDF_CTX * ctx)45*b077aed3SPierre Pronchery void EVP_KDF_CTX_free(EVP_KDF_CTX *ctx)
46*b077aed3SPierre Pronchery {
47*b077aed3SPierre Pronchery     if (ctx == NULL)
48*b077aed3SPierre Pronchery         return;
49*b077aed3SPierre Pronchery     ctx->meth->freectx(ctx->algctx);
50*b077aed3SPierre Pronchery     ctx->algctx = NULL;
51*b077aed3SPierre Pronchery     EVP_KDF_free(ctx->meth);
52*b077aed3SPierre Pronchery     OPENSSL_free(ctx);
53*b077aed3SPierre Pronchery }
54*b077aed3SPierre Pronchery 
EVP_KDF_CTX_dup(const EVP_KDF_CTX * src)55*b077aed3SPierre Pronchery EVP_KDF_CTX *EVP_KDF_CTX_dup(const EVP_KDF_CTX *src)
56*b077aed3SPierre Pronchery {
57*b077aed3SPierre Pronchery     EVP_KDF_CTX *dst;
58*b077aed3SPierre Pronchery 
59*b077aed3SPierre Pronchery     if (src == NULL || src->algctx == NULL || src->meth->dupctx == NULL)
60*b077aed3SPierre Pronchery         return NULL;
61*b077aed3SPierre Pronchery 
62*b077aed3SPierre Pronchery     dst = OPENSSL_malloc(sizeof(*dst));
63*b077aed3SPierre Pronchery     if (dst == NULL) {
64*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
65*b077aed3SPierre Pronchery         return NULL;
66*b077aed3SPierre Pronchery     }
67*b077aed3SPierre Pronchery 
68*b077aed3SPierre Pronchery     memcpy(dst, src, sizeof(*dst));
69*b077aed3SPierre Pronchery     if (!EVP_KDF_up_ref(dst->meth)) {
70*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
71*b077aed3SPierre Pronchery         OPENSSL_free(dst);
72*b077aed3SPierre Pronchery         return NULL;
73*b077aed3SPierre Pronchery     }
74*b077aed3SPierre Pronchery 
75*b077aed3SPierre Pronchery     dst->algctx = src->meth->dupctx(src->algctx);
76*b077aed3SPierre Pronchery     if (dst->algctx == NULL) {
77*b077aed3SPierre Pronchery         EVP_KDF_CTX_free(dst);
78*b077aed3SPierre Pronchery         return NULL;
79*b077aed3SPierre Pronchery     }
80*b077aed3SPierre Pronchery     return dst;
81*b077aed3SPierre Pronchery }
82*b077aed3SPierre Pronchery 
evp_kdf_get_number(const EVP_KDF * kdf)83*b077aed3SPierre Pronchery int evp_kdf_get_number(const EVP_KDF *kdf)
84*b077aed3SPierre Pronchery {
85*b077aed3SPierre Pronchery     return kdf->name_id;
86*b077aed3SPierre Pronchery }
87*b077aed3SPierre Pronchery 
EVP_KDF_get0_name(const EVP_KDF * kdf)88*b077aed3SPierre Pronchery const char *EVP_KDF_get0_name(const EVP_KDF *kdf)
89*b077aed3SPierre Pronchery {
90*b077aed3SPierre Pronchery     return kdf->type_name;
91*b077aed3SPierre Pronchery }
92*b077aed3SPierre Pronchery 
EVP_KDF_get0_description(const EVP_KDF * kdf)93*b077aed3SPierre Pronchery const char *EVP_KDF_get0_description(const EVP_KDF *kdf)
94*b077aed3SPierre Pronchery {
95*b077aed3SPierre Pronchery     return kdf->description;
96*b077aed3SPierre Pronchery }
97*b077aed3SPierre Pronchery 
EVP_KDF_is_a(const EVP_KDF * kdf,const char * name)98*b077aed3SPierre Pronchery int EVP_KDF_is_a(const EVP_KDF *kdf, const char *name)
99*b077aed3SPierre Pronchery {
100*b077aed3SPierre Pronchery     return kdf != NULL && evp_is_a(kdf->prov, kdf->name_id, NULL, name);
101*b077aed3SPierre Pronchery }
102*b077aed3SPierre Pronchery 
EVP_KDF_get0_provider(const EVP_KDF * kdf)103*b077aed3SPierre Pronchery const OSSL_PROVIDER *EVP_KDF_get0_provider(const EVP_KDF *kdf)
104*b077aed3SPierre Pronchery {
105*b077aed3SPierre Pronchery     return kdf->prov;
106*b077aed3SPierre Pronchery }
107*b077aed3SPierre Pronchery 
EVP_KDF_CTX_kdf(EVP_KDF_CTX * ctx)108*b077aed3SPierre Pronchery const EVP_KDF *EVP_KDF_CTX_kdf(EVP_KDF_CTX *ctx)
109*b077aed3SPierre Pronchery {
110*b077aed3SPierre Pronchery     return ctx->meth;
111*b077aed3SPierre Pronchery }
112*b077aed3SPierre Pronchery 
EVP_KDF_CTX_reset(EVP_KDF_CTX * ctx)113*b077aed3SPierre Pronchery void EVP_KDF_CTX_reset(EVP_KDF_CTX *ctx)
114*b077aed3SPierre Pronchery {
115*b077aed3SPierre Pronchery     if (ctx == NULL)
116*b077aed3SPierre Pronchery         return;
117*b077aed3SPierre Pronchery 
118*b077aed3SPierre Pronchery     if (ctx->meth->reset != NULL)
119*b077aed3SPierre Pronchery         ctx->meth->reset(ctx->algctx);
120*b077aed3SPierre Pronchery }
121*b077aed3SPierre Pronchery 
EVP_KDF_CTX_get_kdf_size(EVP_KDF_CTX * ctx)122*b077aed3SPierre Pronchery size_t EVP_KDF_CTX_get_kdf_size(EVP_KDF_CTX *ctx)
123*b077aed3SPierre Pronchery {
124*b077aed3SPierre Pronchery     OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
125*b077aed3SPierre Pronchery     size_t s = 0;
126*b077aed3SPierre Pronchery 
127*b077aed3SPierre Pronchery     if (ctx == NULL)
128*b077aed3SPierre Pronchery         return 0;
129*b077aed3SPierre Pronchery 
130*b077aed3SPierre Pronchery     *params = OSSL_PARAM_construct_size_t(OSSL_KDF_PARAM_SIZE, &s);
131*b077aed3SPierre Pronchery     if (ctx->meth->get_ctx_params != NULL
132*b077aed3SPierre Pronchery         && ctx->meth->get_ctx_params(ctx->algctx, params))
133*b077aed3SPierre Pronchery             return s;
134*b077aed3SPierre Pronchery     if (ctx->meth->get_params != NULL
135*b077aed3SPierre Pronchery         && ctx->meth->get_params(params))
136*b077aed3SPierre Pronchery             return s;
137*b077aed3SPierre Pronchery     return 0;
138*b077aed3SPierre Pronchery }
139*b077aed3SPierre Pronchery 
EVP_KDF_derive(EVP_KDF_CTX * ctx,unsigned char * key,size_t keylen,const OSSL_PARAM params[])140*b077aed3SPierre Pronchery int EVP_KDF_derive(EVP_KDF_CTX *ctx, unsigned char *key, size_t keylen,
141*b077aed3SPierre Pronchery                    const OSSL_PARAM params[])
142*b077aed3SPierre Pronchery {
143*b077aed3SPierre Pronchery     if (ctx == NULL)
144*b077aed3SPierre Pronchery         return 0;
145*b077aed3SPierre Pronchery 
146*b077aed3SPierre Pronchery     return ctx->meth->derive(ctx->algctx, key, keylen, params);
147*b077aed3SPierre Pronchery }
148*b077aed3SPierre Pronchery 
149*b077aed3SPierre Pronchery /*
150*b077aed3SPierre Pronchery  * The {get,set}_params functions return 1 if there is no corresponding
151*b077aed3SPierre Pronchery  * function in the implementation.  This is the same as if there was one,
152*b077aed3SPierre Pronchery  * but it didn't recognise any of the given params, i.e. nothing in the
153*b077aed3SPierre Pronchery  * bag of parameters was useful.
154*b077aed3SPierre Pronchery  */
EVP_KDF_get_params(EVP_KDF * kdf,OSSL_PARAM params[])155*b077aed3SPierre Pronchery int EVP_KDF_get_params(EVP_KDF *kdf, OSSL_PARAM params[])
156*b077aed3SPierre Pronchery {
157*b077aed3SPierre Pronchery     if (kdf->get_params != NULL)
158*b077aed3SPierre Pronchery         return kdf->get_params(params);
159*b077aed3SPierre Pronchery     return 1;
160*b077aed3SPierre Pronchery }
161*b077aed3SPierre Pronchery 
EVP_KDF_CTX_get_params(EVP_KDF_CTX * ctx,OSSL_PARAM params[])162*b077aed3SPierre Pronchery int EVP_KDF_CTX_get_params(EVP_KDF_CTX *ctx, OSSL_PARAM params[])
163*b077aed3SPierre Pronchery {
164*b077aed3SPierre Pronchery     if (ctx->meth->get_ctx_params != NULL)
165*b077aed3SPierre Pronchery         return ctx->meth->get_ctx_params(ctx->algctx, params);
166*b077aed3SPierre Pronchery     return 1;
167*b077aed3SPierre Pronchery }
168*b077aed3SPierre Pronchery 
EVP_KDF_CTX_set_params(EVP_KDF_CTX * ctx,const OSSL_PARAM params[])169*b077aed3SPierre Pronchery int EVP_KDF_CTX_set_params(EVP_KDF_CTX *ctx, const OSSL_PARAM params[])
170*b077aed3SPierre Pronchery {
171*b077aed3SPierre Pronchery     if (ctx->meth->set_ctx_params != NULL)
172*b077aed3SPierre Pronchery         return ctx->meth->set_ctx_params(ctx->algctx, params);
173*b077aed3SPierre Pronchery     return 1;
174*b077aed3SPierre Pronchery }
175*b077aed3SPierre Pronchery 
EVP_KDF_names_do_all(const EVP_KDF * kdf,void (* fn)(const char * name,void * data),void * data)176*b077aed3SPierre Pronchery int EVP_KDF_names_do_all(const EVP_KDF *kdf,
177*b077aed3SPierre Pronchery                          void (*fn)(const char *name, void *data),
178*b077aed3SPierre Pronchery                          void *data)
179*b077aed3SPierre Pronchery {
180*b077aed3SPierre Pronchery     if (kdf->prov != NULL)
181*b077aed3SPierre Pronchery         return evp_names_do_all(kdf->prov, kdf->name_id, fn, data);
182*b077aed3SPierre Pronchery 
183*b077aed3SPierre Pronchery     return 1;
184*b077aed3SPierre Pronchery }
185