Skip to content

Commit a713a5e

Browse files
committed
Infrastructure for returning additional fields in crypto:supports/0, /1
FIPS doc page updated, for enable_fips_mode discourage its manual invocation New store module for algorithms Porting changes from maint Merge in crypto.erl and test SUITE
1 parent efa554e commit a713a5e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+3747
-2116
lines changed

lib/crypto/c_src/Makefile.in

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ CC = @DED_CC@
3636
LD = @DED_LD@
3737
SHELL = /bin/sh
3838
LIBS = @DED_LIBS@
39-
LDFLAGS += @DED_LDFLAGS@
39+
LDFLAGS += @DED_LDFLAGS@ -lstdc++
4040
CFLAGS = @DED_CFLAGS@ @SSL_FLAGS@ @DEFS@
4141

4242
# From configure
@@ -91,14 +91,23 @@ CRYPTO_OBJS = $(OBJDIR)/crypto$(TYPEMARKER).o \
9191
$(OBJDIR)/aead$(TYPEMARKER).o \
9292
$(OBJDIR)/aes$(TYPEMARKER).o \
9393
$(OBJDIR)/algorithms$(TYPEMARKER).o \
94+
$(OBJDIR)/algorithms_collection$(TYPEMARKER).cpp.o \
95+
$(OBJDIR)/algorithms_digest$(TYPEMARKER).cpp.o \
96+
$(OBJDIR)/algorithms_pkey$(TYPEMARKER).cpp.o \
97+
$(OBJDIR)/algorithms_curve$(TYPEMARKER).cpp.o \
98+
$(OBJDIR)/algorithms_kem$(TYPEMARKER).cpp.o \
99+
$(OBJDIR)/algorithms_rsaopt$(TYPEMARKER).cpp.o \
100+
$(OBJDIR)/algorithms_mac$(TYPEMARKER).cpp.o \
101+
$(OBJDIR)/algorithms_cipher$(TYPEMARKER).cpp.o \
102+
$(OBJDIR)/auto_openssl_resource$(TYPEMARKER).cpp.o \
103+
$(OBJDIR)/evp_compat$(TYPEMARKER).cpp.o \
94104
$(OBJDIR)/api_ng$(TYPEMARKER).o \
95105
$(OBJDIR)/atoms$(TYPEMARKER).o \
96106
$(OBJDIR)/bn$(TYPEMARKER).o \
97107
$(OBJDIR)/cipher$(TYPEMARKER).o \
98108
$(OBJDIR)/cmac$(TYPEMARKER).o \
99109
$(OBJDIR)/common$(TYPEMARKER).o \
100110
$(OBJDIR)/dh$(TYPEMARKER).o \
101-
$(OBJDIR)/digest$(TYPEMARKER).o \
102111
$(OBJDIR)/dss$(TYPEMARKER).o \
103112
$(OBJDIR)/ec$(TYPEMARKER).o \
104113
$(OBJDIR)/ecdh$(TYPEMARKER).o \
@@ -119,7 +128,8 @@ CRYPTO_OBJS = $(OBJDIR)/crypto$(TYPEMARKER).o \
119128
$(OBJDIR)/pbkdf2_hmac$(TYPEMARKER).o
120129

121130
CALLBACK_OBJS = $(OBJDIR)/crypto_callback$(TYPEMARKER).o
122-
CRYPTO_STATIC_OBJS = $(patsubst $(OBJDIR)/%$(TYPEMARKER).o,$(OBJDIR)/%_static$(TYPEMARKER).o,$(CRYPTO_OBJS) $(CALLBACK_OBJS))
131+
CRYPTO_STATIC_OBJS = $(patsubst $(OBJDIR)/%$(TYPEMARKER).o,$(OBJDIR)/%_static$(TYPEMARKER).o,$(CRYPTO_OBJS) $(CALLBACK_OBJS)) \
132+
$(patsubst $(OBJDIR)/%$(TYPEMARKER).cpp.o,$(OBJDIR)/%_static$(TYPEMARKER).cpp.o,$(CRYPTO_OBJS) $(CALLBACK_OBJS))
123133

124134
NIF_ARCHIVE = $(LIBDIR)/crypto$(TYPEMARKER).a
125135

@@ -179,8 +189,12 @@ endif
179189

180190
CONFIGURE_ARGS = -DDISABLE_EVP_DH=@DISABLE_EVP_DH@ -DDISABLE_EVP_HMAC=@DISABLE_EVP_HMAC@
181191

182-
ALL_CFLAGS = $(TYPE_FLAGS) $(EXTRA_FLAGS) $(CONFIGURE_ARGS) $(INCLUDES)
192+
ALL_CFLAGS = $(TYPE_FLAGS) $(EXTRA_FLAGS) $(CONFIGURE_ARGS) $(INCLUDES) -std=gnu99
193+
ALL_CXXFLAGS = $(TYPE_FLAGS) $(EXTRA_FLAGS) $(CONFIGURE_ARGS) $(INCLUDES) -std=c++14
194+
195+
# Removed: -Wdeclaration-after-statement, allowed in C99 and C++
183196
ALL_STATIC_CFLAGS = @DED_STATIC_CFLAGS@ $(TYPE_EXTRA_CFLAGS) $(CONFIGURE_ARGS) $(INCLUDES)
197+
ALL_STATIC_CFLAGS := $(filter-out -Wdeclaration-after-statement,$(ALL_STATIC_CFLAGS))
184198

185199
# ----------------------------------------------------
186200
# Targets
@@ -222,6 +236,10 @@ $(OBJDIR)/pkey$(TYPEMARKER).o: pkey.c
222236

223237
# ---- End of Hard-coded removal of deprecated warning for ENGINE function calls
224238

239+
$(OBJDIR)/%$(TYPEMARKER).cpp.o: %.cpp
240+
$(V_at)$(INSTALL_DIR) $(OBJDIR)
241+
$(V_CXX) -MMD -c -o $@ $(ALL_CXXFLAGS) $<
242+
225243
$(OBJDIR)/%$(TYPEMARKER).o: %.c
226244
$(V_at)$(INSTALL_DIR) $(OBJDIR)
227245
$(V_CC) -MMD -c -o $@ $(ALL_CFLAGS) $<

lib/crypto/c_src/aead.c

Lines changed: 69 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@
2424
#include "aes.h"
2525
#include "cipher.h"
2626
#include "info.h"
27-
27+
#include "algorithms_cipher.h"
2828

2929
ErlNifResourceType* aead_cipher_ctx_rtype;
3030

3131
struct aead_cipher_ctx {
32-
const struct cipher_type_t *cipherp;
32+
const cipher_type_C *cipherp;
3333
EVP_CIPHER_CTX *ctx;
3434

3535
ERL_NIF_TERM key;
@@ -71,6 +71,7 @@ ERL_NIF_TERM aead_cipher_init_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM a
7171
struct aead_cipher_ctx *ctx_res = NULL;
7272
ERL_NIF_TERM ret, encflg_arg, type;
7373
ErlNifBinary key;
74+
struct cipher_type_flags_t flags;
7475

7576
if ((ctx_res = enif_alloc_resource(aead_cipher_ctx_rtype, sizeof(struct aead_cipher_ctx))) == NULL)
7677
return EXCP_ERROR(env, "Can't allocate resource");
@@ -107,11 +108,13 @@ ERL_NIF_TERM aead_cipher_init_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM a
107108

108109
if ((ctx_res->cipherp = get_cipher_type(type, key.size)) == NULL)
109110
{ret = EXCP_BADARG_N(env, 0, "Unknown cipher or invalid key size"); goto done;}
110-
if (ctx_res->cipherp->flags & NON_EVP_CIPHER)
111+
112+
flags = get_cipher_type_flags(ctx_res->cipherp);
113+
if (flags.non_evp_cipher)
111114
{ret = EXCP_BADARG_N(env, 0, "Bad cipher"); goto done;}
112-
if (! (ctx_res->cipherp->flags & AEAD_CIPHER) )
115+
if (!flags.aead_cipher)
113116
{ret = EXCP_BADARG_N(env, 0, "Not aead cipher"); goto done;}
114-
if (CIPHER_FORBIDDEN_IN_FIPS(ctx_res->cipherp))
117+
if (is_cipher_forbidden_in_fips(ctx_res->cipherp))
115118
{ret = EXCP_NOTSUP_N(env, 0, "Forbidden in FIPS"); goto done;}
116119

117120
#if defined(HAVE_GCM_EVP_DECRYPT_BUG)
@@ -120,13 +123,19 @@ ERL_NIF_TERM aead_cipher_init_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM a
120123
}
121124
#endif
122125

123-
if (ctx_res->cipherp->cipher.p == NULL)
124-
{ret = EXCP_NOTSUP_N(env, 0, "The cipher is not supported in this libcrypto version"); goto done;}
125-
126-
if ((ctx_res->ctx = EVP_CIPHER_CTX_new()) == NULL)
127-
{ret = EXCP_ERROR(env, "Can't allocate ctx"); goto done;}
128-
if (EVP_CipherInit_ex(ctx_res->ctx, ctx_res->cipherp->cipher.p, NULL, NULL, NULL, ctx_res->encflg) != 1)
129-
{ret = EXCP_ERROR(env, "CipherInit failed"); goto done;}
126+
if (get_cipher_type_resource(ctx_res->cipherp) == NULL) {
127+
ret = EXCP_NOTSUP_N(env, 0, "The cipher is not supported in this libcrypto version");
128+
goto done;
129+
}
130+
if ((ctx_res->ctx = EVP_CIPHER_CTX_new()) == NULL) {
131+
ret = EXCP_ERROR(env, "Can't allocate ctx");
132+
goto done;
133+
}
134+
if (EVP_CipherInit_ex(ctx_res->ctx, get_cipher_type_resource(ctx_res->cipherp),
135+
NULL, NULL, NULL, ctx_res->encflg) != 1) {
136+
ret = EXCP_ERROR(env, "CipherInit failed");
137+
goto done;
138+
}
130139

131140
ret = enif_make_resource(env, ctx_res);
132141

@@ -146,9 +155,11 @@ ERL_NIF_TERM aead_cipher_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]
146155
const EVP_CIPHER *cipher = NULL;
147156
ErlNifBinary key, iv, aad, in, tag;
148157
unsigned int tag_len;
149-
unsigned char *outp, *tagp, *tag_data, *in_data;
158+
unsigned char *outp, *tag_data, *in_data;
150159
ERL_NIF_TERM type, out, out_tag, ret, encflg_arg;
151160
int len, encflg, in_len;
161+
struct cipher_type_flags_t flags;
162+
struct cipher_type_aead_t aead;
152163

153164
if(argc == 7) {
154165
/*
@@ -202,29 +213,45 @@ ERL_NIF_TERM aead_cipher_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]
202213
|| iv.size > INT_MAX
203214
|| in.size > INT_MAX
204215
|| aad.size > INT_MAX)
205-
{ret = EXCP_BADARG_N(env, 5, "binary too long"); goto done;}
216+
{ret = EXCP_BADARG_N(env, 5, "binary too long"); goto done;
217+
}
218+
219+
if ((cipherp = get_cipher_type(type, key.size)) == NULL) {
220+
ret = EXCP_BADARG_N(env, 0, "Unknown cipher or invalid key size");
221+
goto done;
222+
}
206223

207-
if ((cipherp = get_cipher_type(type, key.size)) == NULL)
208-
{ret = EXCP_BADARG_N(env, 0, "Unknown cipher or invalid key size"); goto done;}
209-
if (cipherp->flags & NON_EVP_CIPHER)
210-
{ret = EXCP_BADARG_N(env, 0, "Bad cipher"); goto done;}
211-
if (! (cipherp->flags & AEAD_CIPHER) )
212-
{ret = EXCP_BADARG_N(env, 0, "Not aead cipher"); goto done;}
213-
if (CIPHER_FORBIDDEN_IN_FIPS(cipherp))
214-
{ret = EXCP_NOTSUP_N(env, 0, "Forbidden in FIPS"); goto done;}
224+
flags = get_cipher_type_flags(cipherp);
225+
if (flags.non_evp_cipher) {
226+
ret = EXCP_BADARG_N(env, 0, "Bad cipher");
227+
goto done;
228+
}
229+
if (!flags.aead_cipher) {
230+
ret = EXCP_BADARG_N(env, 0, "Not aead cipher");
231+
goto done;
232+
}
233+
if (is_cipher_forbidden_in_fips(cipherp)) {
234+
ret = EXCP_NOTSUP_N(env, 0, "Forbidden in FIPS");
235+
goto done;
236+
}
215237

216238
#if defined(HAVE_GCM_EVP_DECRYPT_BUG)
217239
if ( !encflg && (cipherp->flags & GCM_MODE)) {
218240
return aes_gcm_decrypt_NO_EVP(env, argc, argv);
219241
}
220242
#endif
221-
if ((cipher = cipherp->cipher.p) == NULL)
222-
{ret = EXCP_NOTSUP_N(env, 0, "The cipher is not supported in this libcrypto version"); goto done;}
223-
224-
if ((ctx = EVP_CIPHER_CTX_new()) == NULL)
225-
{ret = EXCP_ERROR(env, "Can't allocate ctx"); goto done;}
226-
if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, encflg) != 1)
227-
{ret = EXCP_ERROR(env, "CipherInit failed"); goto done;}
243+
if ((cipher = get_cipher_type_resource(cipherp)) == NULL) {
244+
ret = EXCP_NOTSUP_N(env, 0, "The cipher is not supported in this libcrypto version");
245+
goto done;
246+
}
247+
if ((ctx = EVP_CIPHER_CTX_new()) == NULL) {
248+
ret = EXCP_ERROR(env, "Can't allocate ctx");
249+
goto done;
250+
}
251+
if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, encflg) != 1) {
252+
ret = EXCP_ERROR(env, "CipherInit failed");
253+
goto done;
254+
}
228255

229256
} else {
230257
/* argc = 4 {state, IV, InData, AAD } */
@@ -258,17 +285,20 @@ ERL_NIF_TERM aead_cipher_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]
258285
}
259286

260287
cipherp = ctx_res->cipherp;
261-
cipher = cipherp->cipher.p;
288+
cipher = get_cipher_type_resource(cipherp);
262289
ctx = ctx_res->ctx;
263290
}
264291
/* Init done */
265292

266-
if (EVP_CIPHER_CTX_ctrl(ctx, cipherp->extra.aead.ctx_ctrl_set_ivlen, (int)iv.size, NULL) != 1)
293+
aead = get_cipher_type_aead(cipherp);
294+
flags = get_cipher_type_flags(cipherp);
295+
296+
if (EVP_CIPHER_CTX_ctrl(ctx, aead.ctx_ctrl_set_ivlen, (int)iv.size, NULL) != 1)
267297
{ret = EXCP_BADARG_N(env, 2, "Bad IV length"); goto done;}
268298

269299
#if defined(HAVE_CCM)
270-
if (cipherp->flags & CCM_MODE) {
271-
if (EVP_CIPHER_CTX_ctrl(ctx, cipherp->extra.aead.ctx_ctrl_set_tag, (int)tag_len, tag_data) != 1)
300+
if (flags.ccm_mode) {
301+
if (EVP_CIPHER_CTX_ctrl(ctx, aead.ctx_ctrl_set_tag, (int)tag_len, tag_data) != 1)
272302
{ret = EXCP_BADARG_N(env, 5, "Can't set tag"); goto done;}
273303
if (EVP_CipherInit_ex(ctx, NULL, NULL, key.data, iv.data, -1) != 1)
274304
{ret = EXCP_ERROR(env, "Can't set key or iv"); goto done;}
@@ -304,8 +334,8 @@ ERL_NIF_TERM aead_cipher_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]
304334
ret = atom_error;
305335
goto done;
306336
}
307-
if (encflg)
308-
{
337+
if (encflg) {
338+
unsigned char *tagp;
309339
if (argc == 7) {
310340
/* Finalize the encrypted text */
311341
if (EVP_CipherFinal_ex(ctx, outp, &len) != 1)
@@ -314,7 +344,7 @@ ERL_NIF_TERM aead_cipher_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]
314344
/* Get the tag */
315345
if ((tagp = enif_make_new_binary(env, tag_len, &out_tag)) == NULL)
316346
{ret = EXCP_ERROR(env, "Can't make 'Out' binary"); goto done;}
317-
if (EVP_CIPHER_CTX_ctrl(ctx, cipherp->extra.aead.ctx_ctrl_get_tag, (int)tag_len, tagp) != 1)
347+
if (EVP_CIPHER_CTX_ctrl(ctx, aead.ctx_ctrl_get_tag, (int)tag_len, tagp) != 1)
318348
{ret = EXCP_ERROR(env, "Can't get Tag"); goto done;}
319349

320350
/* Make the return value (the tuple with binary crypto text and the tag) */
@@ -324,7 +354,7 @@ ERL_NIF_TERM aead_cipher_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]
324354
{ret = EXCP_ERROR(env, "Encrypt error"); goto done;}
325355
/* Add tag to output end */
326356
tagp = outp + in_len;
327-
if (EVP_CIPHER_CTX_ctrl(ctx, cipherp->extra.aead.ctx_ctrl_get_tag, (int)tag_len, tagp) != 1)
357+
if (EVP_CIPHER_CTX_ctrl(ctx, aead.ctx_ctrl_get_tag, (int)tag_len, tagp) != 1)
328358
{ret = EXCP_ERROR(env, "Can't get Tag"); goto done;}
329359
ret = out;
330360
}
@@ -333,8 +363,8 @@ ERL_NIF_TERM aead_cipher_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]
333363
{
334364
#if defined(HAVE_GCM) || defined(HAVE_CHACHA20_POLY1305)
335365
/* Check the Tag before returning. CCM_MODE does this previously. */
336-
if (!(cipherp->flags & CCM_MODE)) { /* That is, CHACHA20_POLY1305 or GCM_MODE */
337-
if (EVP_CIPHER_CTX_ctrl(ctx, cipherp->extra.aead.ctx_ctrl_set_tag, (int)tag_len, tag_data) != 1)
366+
if (!flags.ccm_mode) { /* That is, CHACHA20_POLY1305 or GCM_MODE */
367+
if (EVP_CIPHER_CTX_ctrl(ctx, aead.ctx_ctrl_set_tag, (int)tag_len, tag_data) != 1)
338368
/* Decrypt error */
339369
{ret = atom_error; goto done;}
340370
/* CCM dislikes EVP_DecryptFinal_ex on decrypting for pre 1.1.1, so we do it only here */

0 commit comments

Comments
 (0)