1 /* 2 * Copyright 2006-2018 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/asn1t.h> 13 #include <openssl/x509.h> 14 #include <openssl/evp.h> 15 #include <openssl/bn.h> 16 #include "internal/evp_int.h" 17 #include "dsa_locl.h" 18 19 /* DSA pkey context structure */ 20 21 typedef struct { 22 /* Parameter gen parameters */ 23 int nbits; /* size of p in bits (default: 1024) */ 24 int qbits; /* size of q in bits (default: 160) */ 25 const EVP_MD *pmd; /* MD for parameter generation */ 26 /* Keygen callback info */ 27 int gentmp[2]; 28 /* message digest */ 29 const EVP_MD *md; /* MD for the signature */ 30 } DSA_PKEY_CTX; 31 32 static int pkey_dsa_init(EVP_PKEY_CTX *ctx) 33 { 34 DSA_PKEY_CTX *dctx = OPENSSL_malloc(sizeof(*dctx)); 35 36 if (dctx == NULL) 37 return 0; 38 dctx->nbits = 1024; 39 dctx->qbits = 160; 40 dctx->pmd = NULL; 41 dctx->md = NULL; 42 43 ctx->data = dctx; 44 ctx->keygen_info = dctx->gentmp; 45 ctx->keygen_info_count = 2; 46 47 return 1; 48 } 49 50 static int pkey_dsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) 51 { 52 DSA_PKEY_CTX *dctx, *sctx; 53 54 if (!pkey_dsa_init(dst)) 55 return 0; 56 sctx = src->data; 57 dctx = dst->data; 58 dctx->nbits = sctx->nbits; 59 dctx->qbits = sctx->qbits; 60 dctx->pmd = sctx->pmd; 61 dctx->md = sctx->md; 62 return 1; 63 } 64 65 static void pkey_dsa_cleanup(EVP_PKEY_CTX *ctx) 66 { 67 DSA_PKEY_CTX *dctx = ctx->data; 68 OPENSSL_free(dctx); 69 } 70 71 static int pkey_dsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, 72 size_t *siglen, const unsigned char *tbs, 73 size_t tbslen) 74 { 75 int ret; 76 unsigned int sltmp; 77 DSA_PKEY_CTX *dctx = ctx->data; 78 DSA *dsa = ctx->pkey->pkey.dsa; 79 80 if (dctx->md != NULL && tbslen != (size_t)EVP_MD_size(dctx->md)) 81 return 0; 82 83 ret = DSA_sign(0, tbs, tbslen, sig, &sltmp, dsa); 84 85 if (ret <= 0) 86 return ret; 87 *siglen = sltmp; 88 return 1; 89 } 90 91 static int pkey_dsa_verify(EVP_PKEY_CTX *ctx, 92 const unsigned char *sig, size_t siglen, 93 const unsigned char *tbs, size_t tbslen) 94 { 95 int ret; 96 DSA_PKEY_CTX *dctx = ctx->data; 97 DSA *dsa = ctx->pkey->pkey.dsa; 98 99 if (dctx->md != NULL && tbslen != (size_t)EVP_MD_size(dctx->md)) 100 return 0; 101 102 ret = DSA_verify(0, tbs, tbslen, sig, siglen, dsa); 103 104 return ret; 105 } 106 107 static int pkey_dsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) 108 { 109 DSA_PKEY_CTX *dctx = ctx->data; 110 111 switch (type) { 112 case EVP_PKEY_CTRL_DSA_PARAMGEN_BITS: 113 if (p1 < 256) 114 return -2; 115 dctx->nbits = p1; 116 return 1; 117 118 case EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS: 119 if (p1 != 160 && p1 != 224 && p1 && p1 != 256) 120 return -2; 121 dctx->qbits = p1; 122 return 1; 123 124 case EVP_PKEY_CTRL_DSA_PARAMGEN_MD: 125 if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 && 126 EVP_MD_type((const EVP_MD *)p2) != NID_sha224 && 127 EVP_MD_type((const EVP_MD *)p2) != NID_sha256) { 128 DSAerr(DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE); 129 return 0; 130 } 131 dctx->pmd = p2; 132 return 1; 133 134 case EVP_PKEY_CTRL_MD: 135 if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 && 136 EVP_MD_type((const EVP_MD *)p2) != NID_dsa && 137 EVP_MD_type((const EVP_MD *)p2) != NID_dsaWithSHA && 138 EVP_MD_type((const EVP_MD *)p2) != NID_sha224 && 139 EVP_MD_type((const EVP_MD *)p2) != NID_sha256 && 140 EVP_MD_type((const EVP_MD *)p2) != NID_sha384 && 141 EVP_MD_type((const EVP_MD *)p2) != NID_sha512) { 142 DSAerr(DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE); 143 return 0; 144 } 145 dctx->md = p2; 146 return 1; 147 148 case EVP_PKEY_CTRL_GET_MD: 149 *(const EVP_MD **)p2 = dctx->md; 150 return 1; 151 152 case EVP_PKEY_CTRL_DIGESTINIT: 153 case EVP_PKEY_CTRL_PKCS7_SIGN: 154 case EVP_PKEY_CTRL_CMS_SIGN: 155 return 1; 156 157 case EVP_PKEY_CTRL_PEER_KEY: 158 DSAerr(DSA_F_PKEY_DSA_CTRL, 159 EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); 160 return -2; 161 default: 162 return -2; 163 164 } 165 } 166 167 static int pkey_dsa_ctrl_str(EVP_PKEY_CTX *ctx, 168 const char *type, const char *value) 169 { 170 if (strcmp(type, "dsa_paramgen_bits") == 0) { 171 int nbits; 172 nbits = atoi(value); 173 return EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits); 174 } 175 if (strcmp(type, "dsa_paramgen_q_bits") == 0) { 176 int qbits = atoi(value); 177 return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, 178 EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS, qbits, 179 NULL); 180 } 181 if (strcmp(type, "dsa_paramgen_md") == 0) { 182 const EVP_MD *md = EVP_get_digestbyname(value); 183 184 if (md == NULL) { 185 DSAerr(DSA_F_PKEY_DSA_CTRL_STR, DSA_R_INVALID_DIGEST_TYPE); 186 return 0; 187 } 188 return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, 189 EVP_PKEY_CTRL_DSA_PARAMGEN_MD, 0, 190 (void *)md); 191 } 192 return -2; 193 } 194 195 static int pkey_dsa_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) 196 { 197 DSA *dsa = NULL; 198 DSA_PKEY_CTX *dctx = ctx->data; 199 BN_GENCB *pcb; 200 int ret; 201 202 if (ctx->pkey_gencb) { 203 pcb = BN_GENCB_new(); 204 if (pcb == NULL) 205 return 0; 206 evp_pkey_set_cb_translate(pcb, ctx); 207 } else 208 pcb = NULL; 209 dsa = DSA_new(); 210 if (dsa == NULL) { 211 BN_GENCB_free(pcb); 212 return 0; 213 } 214 ret = dsa_builtin_paramgen(dsa, dctx->nbits, dctx->qbits, dctx->pmd, 215 NULL, 0, NULL, NULL, NULL, pcb); 216 BN_GENCB_free(pcb); 217 if (ret) 218 EVP_PKEY_assign_DSA(pkey, dsa); 219 else 220 DSA_free(dsa); 221 return ret; 222 } 223 224 static int pkey_dsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) 225 { 226 DSA *dsa = NULL; 227 228 if (ctx->pkey == NULL) { 229 DSAerr(DSA_F_PKEY_DSA_KEYGEN, DSA_R_NO_PARAMETERS_SET); 230 return 0; 231 } 232 dsa = DSA_new(); 233 if (dsa == NULL) 234 return 0; 235 EVP_PKEY_assign_DSA(pkey, dsa); 236 /* Note: if error return, pkey is freed by parent routine */ 237 if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey)) 238 return 0; 239 return DSA_generate_key(pkey->pkey.dsa); 240 } 241 242 const EVP_PKEY_METHOD dsa_pkey_meth = { 243 EVP_PKEY_DSA, 244 EVP_PKEY_FLAG_AUTOARGLEN, 245 pkey_dsa_init, 246 pkey_dsa_copy, 247 pkey_dsa_cleanup, 248 249 0, 250 pkey_dsa_paramgen, 251 252 0, 253 pkey_dsa_keygen, 254 255 0, 256 pkey_dsa_sign, 257 258 0, 259 pkey_dsa_verify, 260 261 0, 0, 262 263 0, 0, 0, 0, 264 265 0, 0, 266 267 0, 0, 268 269 0, 0, 270 271 pkey_dsa_ctrl, 272 pkey_dsa_ctrl_str 273 }; 274