1 #include <lib9.h> 2 #include <kernel.h> 3 #include <isa.h> 4 #include "interp.h" 5 #include "../libinterp/runt.h" 6 #include "mp.h" 7 #include "libsec.h" 8 #include "keys.h" 9 10 static char* pkattr[] = { "p", "alpha", "key", nil }; 11 static char* skattr[] = { "p", "alpha", "key", "!secret", nil }; 12 static char* sigattr[] = { "r", "s", nil }; 13 14 static void* 15 eg_str2sk(char *str, char **strp) 16 { 17 EGpriv *eg; 18 char *p; 19 20 eg = egprivalloc(); 21 eg->pub.p = base64tobig(str, &p); 22 eg->pub.alpha = base64tobig(p, &p); 23 eg->pub.key = base64tobig(p, &p); 24 eg->secret = base64tobig(p, &p); 25 if(strp) 26 *strp = p; 27 return eg; 28 } 29 30 static void* 31 eg_str2pk(char *str, char **strp) 32 { 33 EGpub *eg; 34 char *p; 35 36 eg = egpuballoc(); 37 eg->p = base64tobig(str, &p); 38 eg->alpha = base64tobig(p, &p); 39 eg->key = base64tobig(p, &p); 40 if(strp) 41 *strp = p; 42 return eg; 43 } 44 45 static void* 46 eg_str2sig(char *str, char **strp) 47 { 48 EGsig *eg; 49 char *p; 50 51 eg = egsigalloc(); 52 eg->r = base64tobig(str, &p); 53 eg->s = base64tobig(p, &p); 54 if(strp) 55 *strp = p; 56 return eg; 57 } 58 59 static int 60 eg_sk2str(void *veg, char *buf, int len) 61 { 62 EGpriv *eg; 63 char *cp, *ep; 64 65 eg = (EGpriv*)veg; 66 ep = buf + len - 1; 67 cp = buf; 68 69 cp += snprint(cp, ep - cp, "%U\n", eg->pub.p); 70 cp += snprint(cp, ep - cp, "%U\n", eg->pub.alpha); 71 cp += snprint(cp, ep - cp, "%U\n", eg->pub.key); 72 cp += snprint(cp, ep - cp, "%U\n", eg->secret); 73 *cp = 0; 74 75 return cp - buf; 76 } 77 78 static int 79 eg_pk2str(void *veg, char *buf, int len) 80 { 81 EGpub *eg; 82 char *cp, *ep; 83 84 eg = (EGpub*)veg; 85 ep = buf + len - 1; 86 cp = buf; 87 88 cp += snprint(cp, ep - cp, "%U\n", eg->p); 89 cp += snprint(cp, ep - cp, "%U\n", eg->alpha); 90 cp += snprint(cp, ep - cp, "%U\n", eg->key); 91 *cp = 0; 92 93 return cp - buf; 94 } 95 96 static int 97 eg_sig2str(void *veg, char *buf, int len) 98 { 99 EGsig *eg; 100 char *cp, *ep; 101 102 eg = veg; 103 ep = buf + len - 1; 104 cp = buf; 105 106 cp += snprint(cp, ep - cp, "%U\n", eg->r); 107 cp += snprint(cp, ep - cp, "%U\n", eg->s); 108 *cp = 0; 109 110 return cp - buf; 111 } 112 113 static void* 114 eg_sk2pk(void *vs) 115 { 116 return egprivtopub((EGpriv*)vs); 117 } 118 119 /* generate an el gamal secret key with new params */ 120 static void* 121 eg_gen(int len) 122 { 123 return eggen(len, 0); 124 } 125 126 /* generate an el gamal secret key with same params as a public key */ 127 static void* 128 eg_genfrompk(void *vpub) 129 { 130 EGpub *pub; 131 EGpriv *priv; 132 int nlen; 133 134 pub = vpub; 135 priv = egprivalloc(); 136 priv->pub.p = mpcopy(pub->p); 137 priv->pub.alpha = mpcopy(pub->alpha); 138 nlen = mpsignif(pub->p); 139 pub = &priv->pub; 140 pub->key = mpnew(0); 141 priv->secret = mpnew(0); 142 mprand(nlen-1, genrandom, priv->secret); 143 mpexp(pub->alpha, priv->secret, pub->p, pub->key); 144 return priv; 145 } 146 147 static void* 148 eg_sign(mpint* mp, void *key) 149 { 150 return egsign((EGpriv*)key, mp); 151 } 152 153 static int 154 eg_verify(mpint* mp, void *sig, void *key) 155 { 156 return egverify((EGpub*)key, (EGsig*)sig, mp) == 0; 157 } 158 159 static void 160 eg_freepub(void *a) 161 { 162 egpubfree((EGpub*)a); 163 } 164 165 static void 166 eg_freepriv(void *a) 167 { 168 egprivfree((EGpriv*)a); 169 } 170 171 static void 172 eg_freesig(void *a) 173 { 174 egsigfree((EGsig*)a); 175 } 176 177 SigAlgVec* 178 elgamalinit(void) 179 { 180 SigAlgVec *vec; 181 182 vec = malloc(sizeof(SigAlgVec)); 183 if(vec == nil) 184 return nil; 185 186 vec->name = "elgamal"; 187 188 vec->pkattr = pkattr; 189 vec->skattr = skattr; 190 vec->sigattr = sigattr; 191 192 vec->str2sk = eg_str2sk; 193 vec->str2pk = eg_str2pk; 194 vec->str2sig = eg_str2sig; 195 196 vec->sk2str = eg_sk2str; 197 vec->pk2str = eg_pk2str; 198 vec->sig2str = eg_sig2str; 199 200 vec->sk2pk = eg_sk2pk; 201 202 vec->gensk = eg_gen; 203 vec->genskfrompk = eg_genfrompk; 204 vec->sign = eg_sign; 205 vec->verify = eg_verify; 206 207 vec->skfree = eg_freepriv; 208 vec->pkfree = eg_freepub; 209 vec->sigfree = eg_freesig; 210 211 return vec; 212 } 213