1 /* dsa.c - DSA signature algorithm
2 * Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
6 * GnuPG is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * GnuPG is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
21 #include <linux/kernel.h>
22 #include <linux/crypto/mpi.h>
23 #include <asm/errno.h>
27 * perform DSA algorithm signature verification
29 int DSA_verify(const MPI datahash, const MPI sig[], const MPI pkey[])
32 MPI w = NULL, u1 = NULL, u2 = NULL, v = NULL;
39 !pkey[0] || !pkey[1] || !pkey[2] || !pkey[3])
42 p = pkey[0]; /* prime */
43 q = pkey[1]; /* group order */
44 g = pkey[2]; /* group generator */
45 y = pkey[3]; /* g^x mod p */
49 if (!(mpi_cmp_ui(r, 0) > 0 && mpi_cmp(r, q) < 0)) {
50 printk("DSA_verify assertion failed [0 < r < q]\n");
54 if (!(mpi_cmp_ui(s, 0) > 0 && mpi_cmp(s, q) < 0)) {
55 printk("DSA_verify assertion failed [0 < s < q]\n");
60 w = mpi_alloc(mpi_get_nlimbs(q)); if (!w ) goto cleanup;
61 u1 = mpi_alloc(mpi_get_nlimbs(q)); if (!u1) goto cleanup;
62 u2 = mpi_alloc(mpi_get_nlimbs(q)); if (!u2) goto cleanup;
63 v = mpi_alloc(mpi_get_nlimbs(p)); if (!v ) goto cleanup;
65 /* w = s^(-1) mod q */
66 if (mpi_invm(w, s, q) < 0)
69 /* u1 = (datahash * w) mod q */
70 if (mpi_mulm(u1, datahash, w, q) < 0)
73 /* u2 = r * w mod q */
74 if (mpi_mulm(u2, r, w, q) < 0)
77 /* v = g^u1 * y^u2 mod p mod q */
78 base[0] = g; exp[0] = u1;
79 base[1] = y; exp[1] = u2;
80 base[2] = NULL; exp[2] = NULL;
82 if (mpi_mulpowm(v, base, exp, p) < 0)
85 if (mpi_fdiv_r(v, v, q) < 0)
88 rc = (mpi_cmp(v, r) == 0) ? 0 : -EKEYREJECTED;