Implement Aria GCM/CCM Modes and TLS cipher suites
[openssl.git] / crypto / evp / pmeth_gn.c
1 /*
2  * Copyright 2006-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 <stdlib.h>
12 #include "internal/cryptlib.h"
13 #include <openssl/objects.h>
14 #include <openssl/evp.h>
15 #include "internal/bn_int.h"
16 #include "internal/evp_int.h"
17
18 int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx)
19 {
20     int ret;
21     if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen) {
22         EVPerr(EVP_F_EVP_PKEY_PARAMGEN_INIT,
23                EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
24         return -2;
25     }
26     ctx->operation = EVP_PKEY_OP_PARAMGEN;
27     if (!ctx->pmeth->paramgen_init)
28         return 1;
29     ret = ctx->pmeth->paramgen_init(ctx);
30     if (ret <= 0)
31         ctx->operation = EVP_PKEY_OP_UNDEFINED;
32     return ret;
33 }
34
35 int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey)
36 {
37     int ret;
38     if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen) {
39         EVPerr(EVP_F_EVP_PKEY_PARAMGEN,
40                EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
41         return -2;
42     }
43
44     if (ctx->operation != EVP_PKEY_OP_PARAMGEN) {
45         EVPerr(EVP_F_EVP_PKEY_PARAMGEN, EVP_R_OPERATON_NOT_INITIALIZED);
46         return -1;
47     }
48
49     if (ppkey == NULL)
50         return -1;
51
52     if (*ppkey == NULL)
53         *ppkey = EVP_PKEY_new();
54
55     if (*ppkey == NULL) {
56         EVPerr(EVP_F_EVP_PKEY_PARAMGEN, ERR_R_MALLOC_FAILURE);
57         return -1;
58     }
59
60     ret = ctx->pmeth->paramgen(ctx, *ppkey);
61     if (ret <= 0) {
62         EVP_PKEY_free(*ppkey);
63         *ppkey = NULL;
64     }
65     return ret;
66 }
67
68 int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx)
69 {
70     int ret;
71     if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) {
72         EVPerr(EVP_F_EVP_PKEY_KEYGEN_INIT,
73                EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
74         return -2;
75     }
76     ctx->operation = EVP_PKEY_OP_KEYGEN;
77     if (!ctx->pmeth->keygen_init)
78         return 1;
79     ret = ctx->pmeth->keygen_init(ctx);
80     if (ret <= 0)
81         ctx->operation = EVP_PKEY_OP_UNDEFINED;
82     return ret;
83 }
84
85 int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey)
86 {
87     int ret;
88
89     if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) {
90         EVPerr(EVP_F_EVP_PKEY_KEYGEN,
91                EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
92         return -2;
93     }
94     if (ctx->operation != EVP_PKEY_OP_KEYGEN) {
95         EVPerr(EVP_F_EVP_PKEY_KEYGEN, EVP_R_OPERATON_NOT_INITIALIZED);
96         return -1;
97     }
98
99     if (ppkey == NULL)
100         return -1;
101
102     if (*ppkey == NULL)
103         *ppkey = EVP_PKEY_new();
104     if (*ppkey == NULL)
105         return -1;
106
107     ret = ctx->pmeth->keygen(ctx, *ppkey);
108     if (ret <= 0) {
109         EVP_PKEY_free(*ppkey);
110         *ppkey = NULL;
111     }
112     return ret;
113 }
114
115 void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb)
116 {
117     ctx->pkey_gencb = cb;
118 }
119
120 EVP_PKEY_gen_cb *EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx)
121 {
122     return ctx->pkey_gencb;
123 }
124
125 /*
126  * "translation callback" to call EVP_PKEY_CTX callbacks using BN_GENCB style
127  * callbacks.
128  */
129
130 static int trans_cb(int a, int b, BN_GENCB *gcb)
131 {
132     EVP_PKEY_CTX *ctx = BN_GENCB_get_arg(gcb);
133     ctx->keygen_info[0] = a;
134     ctx->keygen_info[1] = b;
135     return ctx->pkey_gencb(ctx);
136 }
137
138 void evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx)
139 {
140     BN_GENCB_set(cb, trans_cb, ctx);
141 }
142
143 int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx)
144 {
145     if (idx == -1)
146         return ctx->keygen_info_count;
147     if (idx < 0 || idx > ctx->keygen_info_count)
148         return 0;
149     return ctx->keygen_info[idx];
150 }
151
152 EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e,
153                                const unsigned char *key, int keylen)
154 {
155     EVP_PKEY_CTX *mac_ctx = NULL;
156     EVP_PKEY *mac_key = NULL;
157     mac_ctx = EVP_PKEY_CTX_new_id(type, e);
158     if (!mac_ctx)
159         return NULL;
160     if (EVP_PKEY_keygen_init(mac_ctx) <= 0)
161         goto merr;
162     if (EVP_PKEY_CTX_set_mac_key(mac_ctx, key, keylen) <= 0)
163         goto merr;
164     if (EVP_PKEY_keygen(mac_ctx, &mac_key) <= 0)
165         goto merr;
166  merr:
167     EVP_PKEY_CTX_free(mac_ctx);
168     return mac_key;
169 }