/src/openssl/crypto/cmac/cm_pmeth.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright 2010-2016 The OpenSSL Project Authors. All Rights Reserved. |
3 | | * |
4 | | * Licensed under the OpenSSL license (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 <stdio.h> |
11 | | #include "internal/cryptlib.h" |
12 | | #include <openssl/x509.h> |
13 | | #include <openssl/x509v3.h> |
14 | | #include <openssl/evp.h> |
15 | | #include <openssl/cmac.h> |
16 | | #include "internal/evp_int.h" |
17 | | |
18 | | /* The context structure and "key" is simply a CMAC_CTX */ |
19 | | |
20 | | static int pkey_cmac_init(EVP_PKEY_CTX *ctx) |
21 | 0 | { |
22 | 0 | ctx->data = CMAC_CTX_new(); |
23 | 0 | if (ctx->data == NULL) |
24 | 0 | return 0; |
25 | 0 | ctx->keygen_info_count = 0; |
26 | 0 | return 1; |
27 | 0 | } |
28 | | |
29 | | static int pkey_cmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) |
30 | 0 | { |
31 | 0 | if (!pkey_cmac_init(dst)) |
32 | 0 | return 0; |
33 | 0 | if (!CMAC_CTX_copy(dst->data, src->data)) |
34 | 0 | return 0; |
35 | 0 | return 1; |
36 | 0 | } |
37 | | |
38 | | static void pkey_cmac_cleanup(EVP_PKEY_CTX *ctx) |
39 | 0 | { |
40 | 0 | CMAC_CTX_free(ctx->data); |
41 | 0 | } |
42 | | |
43 | | static int pkey_cmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) |
44 | 0 | { |
45 | 0 | CMAC_CTX *cmkey = CMAC_CTX_new(); |
46 | 0 | CMAC_CTX *cmctx = ctx->data; |
47 | 0 | if (cmkey == NULL) |
48 | 0 | return 0; |
49 | 0 | if (!CMAC_CTX_copy(cmkey, cmctx)) { |
50 | 0 | CMAC_CTX_free(cmkey); |
51 | 0 | return 0; |
52 | 0 | } |
53 | 0 | EVP_PKEY_assign(pkey, EVP_PKEY_CMAC, cmkey); |
54 | 0 |
|
55 | 0 | return 1; |
56 | 0 | } |
57 | | |
58 | | static int int_update(EVP_MD_CTX *ctx, const void *data, size_t count) |
59 | 0 | { |
60 | 0 | if (!CMAC_Update(EVP_MD_CTX_pkey_ctx(ctx)->data, data, count)) |
61 | 0 | return 0; |
62 | 0 | return 1; |
63 | 0 | } |
64 | | |
65 | | static int cmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) |
66 | 0 | { |
67 | 0 | EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT); |
68 | 0 | EVP_MD_CTX_set_update_fn(mctx, int_update); |
69 | 0 | return 1; |
70 | 0 | } |
71 | | |
72 | | static int cmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, |
73 | | EVP_MD_CTX *mctx) |
74 | 0 | { |
75 | 0 | return CMAC_Final(ctx->data, sig, siglen); |
76 | 0 | } |
77 | | |
78 | | static int pkey_cmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) |
79 | 0 | { |
80 | 0 | CMAC_CTX *cmctx = ctx->data; |
81 | 0 | switch (type) { |
82 | 0 |
|
83 | 0 | case EVP_PKEY_CTRL_SET_MAC_KEY: |
84 | 0 | if (!p2 || p1 < 0) |
85 | 0 | return 0; |
86 | 0 | if (!CMAC_Init(cmctx, p2, p1, NULL, NULL)) |
87 | 0 | return 0; |
88 | 0 | break; |
89 | 0 |
|
90 | 0 | case EVP_PKEY_CTRL_CIPHER: |
91 | 0 | if (!CMAC_Init(cmctx, NULL, 0, p2, ctx->engine)) |
92 | 0 | return 0; |
93 | 0 | break; |
94 | 0 |
|
95 | 0 | case EVP_PKEY_CTRL_MD: |
96 | 0 | if (ctx->pkey && !CMAC_CTX_copy(ctx->data, |
97 | 0 | (CMAC_CTX *)ctx->pkey->pkey.ptr)) |
98 | 0 | return 0; |
99 | 0 | if (!CMAC_Init(cmctx, NULL, 0, NULL, NULL)) |
100 | 0 | return 0; |
101 | 0 | break; |
102 | 0 |
|
103 | 0 | default: |
104 | 0 | return -2; |
105 | 0 | |
106 | 0 | } |
107 | 0 | return 1; |
108 | 0 | } |
109 | | |
110 | | static int pkey_cmac_ctrl_str(EVP_PKEY_CTX *ctx, |
111 | | const char *type, const char *value) |
112 | | { |
113 | | if (!value) { |
114 | | return 0; |
115 | | } |
116 | | if (strcmp(type, "cipher") == 0) { |
117 | | const EVP_CIPHER *c; |
118 | | c = EVP_get_cipherbyname(value); |
119 | | if (!c) |
120 | | return 0; |
121 | | return pkey_cmac_ctrl(ctx, EVP_PKEY_CTRL_CIPHER, -1, (void *)c); |
122 | | } |
123 | | if (strcmp(type, "key") == 0) |
124 | | return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, value); |
125 | | if (strcmp(type, "hexkey") == 0) |
126 | | return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, value); |
127 | | return -2; |
128 | | } |
129 | | |
130 | | const EVP_PKEY_METHOD cmac_pkey_meth = { |
131 | | EVP_PKEY_CMAC, |
132 | | EVP_PKEY_FLAG_SIGCTX_CUSTOM, |
133 | | pkey_cmac_init, |
134 | | pkey_cmac_copy, |
135 | | pkey_cmac_cleanup, |
136 | | |
137 | | 0, 0, |
138 | | |
139 | | 0, |
140 | | pkey_cmac_keygen, |
141 | | |
142 | | 0, 0, |
143 | | |
144 | | 0, 0, |
145 | | |
146 | | 0, 0, |
147 | | |
148 | | cmac_signctx_init, |
149 | | cmac_signctx, |
150 | | |
151 | | 0, 0, |
152 | | |
153 | | 0, 0, |
154 | | |
155 | | 0, 0, |
156 | | |
157 | | 0, 0, |
158 | | |
159 | | pkey_cmac_ctrl, |
160 | | pkey_cmac_ctrl_str |
161 | | }; |