Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: HTTPClient-SSL HTTPClient HTTPClient-SSL http_access ... more
dsa.c
00001 /* dsa.c 00002 * 00003 * Copyright (C) 2006-2014 wolfSSL Inc. 00004 * 00005 * This file is part of CyaSSL. 00006 * 00007 * CyaSSL is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * CyaSSL is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 00020 */ 00021 00022 #ifdef HAVE_CONFIG_H 00023 #include <config.h> 00024 #endif 00025 00026 #include <cyassl/ctaocrypt/settings.h> 00027 00028 #ifndef NO_DSA 00029 00030 #include <cyassl/ctaocrypt/dsa.h> 00031 #include <cyassl/ctaocrypt/sha.h> 00032 #include <cyassl/ctaocrypt/random.h> 00033 #include <cyassl/ctaocrypt/error-crypt.h> 00034 00035 00036 enum { 00037 DSA_HALF_SIZE = 20, /* r and s size */ 00038 DSA_SIG_SIZE = 40 /* signature size */ 00039 }; 00040 00041 00042 #ifndef min 00043 00044 static INLINE word32 min(word32 a, word32 b) 00045 { 00046 return a > b ? b : a; 00047 } 00048 00049 #endif /* min */ 00050 00051 00052 void InitDsaKey(DsaKey* key) 00053 { 00054 key->type = -1; /* haven't decided yet */ 00055 00056 /* TomsFastMath doesn't use memory allocation */ 00057 #ifndef USE_FAST_MATH 00058 key->p.dp = 0; /* public alloc parts */ 00059 key->q.dp = 0; 00060 key->g.dp = 0; 00061 key->y.dp = 0; 00062 00063 key->x.dp = 0; /* private alloc parts */ 00064 #endif 00065 } 00066 00067 00068 void FreeDsaKey(DsaKey* key) 00069 { 00070 (void)key; 00071 /* TomsFastMath doesn't use memory allocation */ 00072 #ifndef USE_FAST_MATH 00073 if (key->type == DSA_PRIVATE) 00074 mp_clear(&key->x); 00075 mp_clear(&key->y); 00076 mp_clear(&key->g); 00077 mp_clear(&key->q); 00078 mp_clear(&key->p); 00079 #endif 00080 } 00081 00082 00083 int DsaSign(const byte* digest, byte* out, DsaKey* key, RNG* rng) 00084 { 00085 mp_int k, kInv, r, s, H; 00086 int ret, sz; 00087 byte buffer[DSA_HALF_SIZE]; 00088 00089 sz = min(sizeof(buffer), mp_unsigned_bin_size(&key->q)); 00090 00091 /* generate k */ 00092 ret = RNG_GenerateBlock(rng, buffer, sz); 00093 if (ret != 0) 00094 return ret; 00095 00096 buffer[0] |= 0x0C; 00097 00098 if (mp_init_multi(&k, &kInv, &r, &s, &H, 0) != MP_OKAY) 00099 return MP_INIT_E; 00100 00101 if (mp_read_unsigned_bin(&k, buffer, sz) != MP_OKAY) 00102 ret = MP_READ_E; 00103 00104 if (ret == 0 && mp_cmp_d(&k, 1) != MP_GT) 00105 ret = MP_CMP_E; 00106 00107 /* inverse k mod q */ 00108 if (ret == 0 && mp_invmod(&k, &key->q, &kInv) != MP_OKAY) 00109 ret = MP_INVMOD_E; 00110 00111 /* generate r, r = (g exp k mod p) mod q */ 00112 if (ret == 0 && mp_exptmod(&key->g, &k, &key->p, &r) != MP_OKAY) 00113 ret = MP_EXPTMOD_E; 00114 00115 if (ret == 0 && mp_mod(&r, &key->q, &r) != MP_OKAY) 00116 ret = MP_MOD_E; 00117 00118 /* generate H from sha digest */ 00119 if (ret == 0 && mp_read_unsigned_bin(&H, digest,SHA_DIGEST_SIZE) != MP_OKAY) 00120 ret = MP_READ_E; 00121 00122 /* generate s, s = (kInv * (H + x*r)) % q */ 00123 if (ret == 0 && mp_mul(&key->x, &r, &s) != MP_OKAY) 00124 ret = MP_MUL_E; 00125 00126 if (ret == 0 && mp_add(&s, &H, &s) != MP_OKAY) 00127 ret = MP_ADD_E; 00128 00129 if (ret == 0 && mp_mulmod(&s, &kInv, &key->q, &s) != MP_OKAY) 00130 ret = MP_MULMOD_E; 00131 00132 /* write out */ 00133 if (ret == 0) { 00134 int rSz = mp_unsigned_bin_size(&r); 00135 int sSz = mp_unsigned_bin_size(&s); 00136 00137 if (rSz == DSA_HALF_SIZE - 1) { 00138 out[0] = 0; 00139 out++; 00140 } 00141 00142 if (mp_to_unsigned_bin(&r, out) != MP_OKAY) 00143 ret = MP_TO_E; 00144 else { 00145 if (sSz == DSA_HALF_SIZE - 1) { 00146 out[rSz] = 0; 00147 out++; 00148 } 00149 ret = mp_to_unsigned_bin(&s, out + rSz); 00150 } 00151 } 00152 00153 mp_clear(&H); 00154 mp_clear(&s); 00155 mp_clear(&r); 00156 mp_clear(&kInv); 00157 mp_clear(&k); 00158 00159 return ret; 00160 } 00161 00162 00163 int DsaVerify(const byte* digest, const byte* sig, DsaKey* key, int* answer) 00164 { 00165 mp_int w, u1, u2, v, r, s; 00166 int ret = 0; 00167 00168 if (mp_init_multi(&w, &u1, &u2, &v, &r, &s) != MP_OKAY) 00169 return MP_INIT_E; 00170 00171 /* set r and s from signature */ 00172 if (mp_read_unsigned_bin(&r, sig, DSA_HALF_SIZE) != MP_OKAY || 00173 mp_read_unsigned_bin(&s, sig + DSA_HALF_SIZE, DSA_HALF_SIZE) != MP_OKAY) 00174 ret = MP_READ_E; 00175 00176 /* sanity checks */ 00177 00178 00179 /* put H into u1 from sha digest */ 00180 if (ret == 0 && mp_read_unsigned_bin(&u1,digest,SHA_DIGEST_SIZE) != MP_OKAY) 00181 ret = MP_READ_E; 00182 00183 /* w = s invmod q */ 00184 if (ret == 0 && mp_invmod(&s, &key->q, &w) != MP_OKAY) 00185 ret = MP_INVMOD_E; 00186 00187 /* u1 = (H * w) % q */ 00188 if (ret == 0 && mp_mulmod(&u1, &w, &key->q, &u1) != MP_OKAY) 00189 ret = MP_MULMOD_E; 00190 00191 /* u2 = (r * w) % q */ 00192 if (ret == 0 && mp_mulmod(&r, &w, &key->q, &u2) != MP_OKAY) 00193 ret = MP_MULMOD_E; 00194 00195 /* verify v = ((g^u1 * y^u2) mod p) mod q */ 00196 if (ret == 0 && mp_exptmod(&key->g, &u1, &key->p, &u1) != MP_OKAY) 00197 ret = MP_EXPTMOD_E; 00198 00199 if (ret == 0 && mp_exptmod(&key->y, &u2, &key->p, &u2) != MP_OKAY) 00200 ret = MP_EXPTMOD_E; 00201 00202 if (ret == 0 && mp_mulmod(&u1, &u2, &key->p, &v) != MP_OKAY) 00203 ret = MP_MULMOD_E; 00204 00205 if (ret == 0 && mp_mod(&v, &key->q, &v) != MP_OKAY) 00206 ret = MP_MULMOD_E; 00207 00208 /* do they match */ 00209 if (ret == 0 && mp_cmp(&r, &v) == MP_EQ) 00210 *answer = 1; 00211 else 00212 *answer = 0; 00213 00214 mp_clear(&s); 00215 mp_clear(&r); 00216 mp_clear(&u1); 00217 mp_clear(&u2); 00218 mp_clear(&w); 00219 mp_clear(&v); 00220 00221 return ret; 00222 } 00223 00224 00225 #endif /* NO_DSA */ 00226 00227
Generated on Wed Jul 13 2022 02:18:39 by
 1.7.2
 1.7.2 
    