4c1defc19d1663148a79c1cce10f4970479ca62b
5 * (c) 2004 Straylight/Edgeware
8 /*----- Licensing notice --------------------------------------------------*
10 * This file is part of Catacomb.
12 * Catacomb is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU Library General Public License as
14 * published by the Free Software Foundation; either version 2 of the
15 * License, or (at your option) any later version.
17 * Catacomb is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Library General Public License for more details.
22 * You should have received a copy of the GNU Library General Public
23 * License along with Catacomb; if not, write to the Free
24 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
28 /*----- Header files ------------------------------------------------------*/
30 #define _FILE_OFFSET_BITS 64
34 #include <mLib/macros.h>
35 #include <mLib/report.h>
55 /*----- Main code ---------------------------------------------------------*/
57 /* --- RSA PKCS1 --- */
59 typedef struct rsap1_sigctx
{
65 static sig
*rsap1_siginit(key
*k
, void *kd
, const gchash
*hc
)
67 rsap1_sigctx
*rs
= CREATE(rsap1_sigctx
);
68 rsa_privcreate(&rs
->rp
, kd
, &rand_global
);
69 rs
->p1
.r
= &rand_global
;
71 rs
->p1
.epsz
= strlen(hc
->name
) + 1;
76 static int rsap1_sigdoit(sig
*s
, dstr
*d
)
78 rsap1_sigctx
*rs
= (rsap1_sigctx
*)s
;
80 mp
*m
= rsa_sign(&rs
->rp
, MP_NEW
,
81 GH_DONE(s
->h
, 0), GH_CLASS(s
->h
)->hashsz
,
82 pkcs1_sigencode
, &rs
->p1
);
84 n
= mp_octets(rs
->rp
.rp
->n
); dstr_ensure(d
, n
); mp_storeb(m
, d
->buf
, n
);
85 d
->len
+= n
; mp_drop(m
);
89 static const char *rsa_lengthcheck(mp
*n
)
91 if (mp_bits(n
) < 1024) return ("key too short");
95 static const char *rsap1_sigcheck(sig
*s
)
97 rsap1_sigctx
*rs
= (rsap1_sigctx
*)s
;
99 if ((e
= rsa_lengthcheck(rs
->rp
.rp
->n
)) != 0) return (e
);
103 static void rsap1_sigdestroy(sig
*s
)
105 rsap1_sigctx
*rs
= (rsap1_sigctx
*)s
;
106 rsa_privdestroy(&rs
->rp
);
110 static const sigops rsap1_sig
= {
111 rsa_privfetch
, sizeof(rsa_priv
),
112 rsap1_siginit
, rsap1_sigdoit
, rsap1_sigcheck
, rsap1_sigdestroy
115 typedef struct rsap1_vrfctx
{
121 static sig
*rsap1_vrfinit(key
*k
, void *kd
, const gchash
*hc
)
123 rsap1_vrfctx
*rv
= CREATE(rsap1_vrfctx
);
124 rsa_pubcreate(&rv
->rp
, kd
);
125 rv
->p1
.r
= &rand_global
;
126 rv
->p1
.ep
= hc
->name
;
127 rv
->p1
.epsz
= strlen(hc
->name
) + 1;
132 static int rsap1_vrfdoit(sig
*s
, dstr
*d
)
134 rsap1_vrfctx
*rv
= (rsap1_vrfctx
*)s
;
135 mp
*m
= mp_loadb(MP_NEW
, d
->buf
, d
->len
);
136 int rc
= rsa_verify(&rv
->rp
, m
,
137 GH_DONE(s
->h
, 0), GH_CLASS(s
->h
)->hashsz
,
138 0, pkcs1_sigdecode
, &rv
->p1
);
143 static const char *rsap1_vrfcheck(sig
*s
)
145 rsap1_vrfctx
*rv
= (rsap1_vrfctx
*)s
;
147 if ((e
= rsa_lengthcheck(rv
->rp
.rp
->n
)) != 0) return (e
);
151 static void rsap1_vrfdestroy(sig
*s
)
153 rsap1_vrfctx
*rv
= (rsap1_vrfctx
*)s
;
154 rsa_pubdestroy(&rv
->rp
);
158 static const sigops rsap1_vrf
= {
159 rsa_pubfetch
, sizeof(rsa_pub
),
160 rsap1_vrfinit
, rsap1_vrfdoit
, rsap1_vrfcheck
, rsap1_vrfdestroy
163 /* --- RSA PSS --- */
165 static const gccipher
*getmgf(key
*k
, const gchash
*hc
)
171 if ((mm
= key_getattr(0, k
, "mgf")) == 0) {
172 dstr_putf(&d
, "%s-mgf", hc
->name
);
175 if ((gc
= gcipher_byname(mm
)) == 0)
176 die(EXIT_FAILURE
, "unknown encryption scheme `%s'", mm
);
181 typedef struct rsapss_sigctx
{
187 static sig
*rsapss_siginit(key
*k
, void *kd
, const gchash
*hc
)
189 rsapss_sigctx
*rs
= CREATE(rsapss_sigctx
);
190 rsa_privcreate(&rs
->rp
, kd
, &rand_global
);
192 rs
->p
.r
= &rand_global
;
193 rs
->p
.cc
= getmgf(k
, hc
);
195 rs
->p
.ssz
= hc
->hashsz
;
199 static int rsapss_sigdoit(sig
*s
, dstr
*d
)
201 rsapss_sigctx
*rs
= (rsapss_sigctx
*)s
;
203 mp
*m
= rsa_sign(&rs
->rp
, MP_NEW
,
204 GH_DONE(s
->h
, 0), GH_CLASS(s
->h
)->hashsz
,
207 n
= mp_octets(rs
->rp
.rp
->n
); dstr_ensure(d
, n
); mp_storeb(m
, d
->buf
, n
);
208 d
->len
+= n
; mp_drop(m
);
212 static const char *rsapss_sigcheck(sig
*s
)
214 rsapss_sigctx
*rs
= (rsapss_sigctx
*)s
;
216 if ((e
= rsa_lengthcheck(rs
->rp
.rp
->n
)) != 0) return (e
);
220 static void rsapss_sigdestroy(sig
*s
)
222 rsapss_sigctx
*rs
= (rsapss_sigctx
*)s
;
223 rsa_privdestroy(&rs
->rp
);
227 static const sigops rsapss_sig
= {
228 rsa_privfetch
, sizeof(rsa_priv
),
229 rsapss_siginit
, rsapss_sigdoit
, rsapss_sigcheck
, rsapss_sigdestroy
232 typedef struct rsapss_vrfctx
{
238 static sig
*rsapss_vrfinit(key
*k
, void *kd
, const gchash
*hc
)
240 rsapss_vrfctx
*rv
= CREATE(rsapss_vrfctx
);
241 rsa_pubcreate(&rv
->rp
, kd
);
243 rv
->p
.r
= &rand_global
;
244 rv
->p
.cc
= getmgf(k
, hc
);
246 rv
->p
.ssz
= hc
->hashsz
;
250 static int rsapss_vrfdoit(sig
*s
, dstr
*d
)
252 rsapss_vrfctx
*rv
= (rsapss_vrfctx
*)s
;
253 mp
*m
= mp_loadb(MP_NEW
, d
->buf
, d
->len
);
254 int rc
= rsa_verify(&rv
->rp
, m
,
255 GH_DONE(s
->h
, 0), GH_CLASS(s
->h
)->hashsz
,
256 0, pss_decode
, &rv
->p
);
261 static const char *rsapss_vrfcheck(sig
*s
)
263 rsapss_vrfctx
*rv
= (rsapss_vrfctx
*)s
;
265 if ((e
= rsa_lengthcheck(rv
->rp
.rp
->n
)) != 0) return (e
);
269 static void rsapss_vrfdestroy(sig
*s
)
271 rsapss_vrfctx
*rv
= (rsapss_vrfctx
*)s
;
272 rsa_pubdestroy(&rv
->rp
);
276 static const sigops rsapss_vrf
= {
277 rsa_pubfetch
, sizeof(rsa_pub
),
278 rsapss_vrfinit
, rsapss_vrfdoit
, rsapss_vrfcheck
, rsapss_vrfdestroy
281 /* --- DSA and ECDSA --- */
283 typedef struct dsa_sigctx
{
288 static void dsa_initcommon(dsa_sigctx
*ds
, const gchash
*hc
,
291 ds
->g
.r
= &rand_global
;
297 static dsa_sigctx
*dsa_doinit(key
*k
, const gprime_param
*gp
,
298 mp
*y
, const gchash
*hc
,
299 group
*(*makegroup
)(const gprime_param
*),
302 dsa_sigctx
*ds
= CREATE(dsa_sigctx
);
306 if ((ds
->g
.g
= makegroup(gp
)) == 0)
307 die(EXIT_FAILURE
, "bad %s group in key `%s'", what
, t
.buf
);
308 ds
->g
.p
= G_CREATE(ds
->g
.g
);
309 if (G_FROMINT(ds
->g
.g
, ds
->g
.p
, y
))
310 die(EXIT_FAILURE
, "bad public key in key `%s'", t
.buf
);
311 dsa_initcommon(ds
, hc
, t
.buf
);
316 static dsa_sigctx
*ecdsa_doinit(key
*k
, const char *cstr
,
317 ec
*y
, const gchash
*hc
)
319 dsa_sigctx
*ds
= CREATE(dsa_sigctx
);
325 if ((e
= ec_getinfo(&ei
, cstr
)) != 0)
326 die(EXIT_FAILURE
, "bad curve in key `%s': %s", t
.buf
, e
);
327 ds
->g
.g
= group_ec(&ei
);
328 ds
->g
.p
= G_CREATE(ds
->g
.g
);
329 if (G_FROMEC(ds
->g
.g
, ds
->g
.p
, y
))
330 die(EXIT_FAILURE
, "bad public key in key `%s'", t
.buf
);
331 dsa_initcommon(ds
, hc
, t
.buf
);
336 static sig
*dsa_siginit(key
*k
, void *kd
, const gchash
*hc
)
339 dsa_sigctx
*ds
= dsa_doinit(k
, &dp
->dp
, dp
->y
, hc
, group_prime
, "prime");
340 ds
->g
.u
= MP_COPY(dp
->x
);
344 static sig
*bindsa_siginit(key
*k
, void *kd
, const gchash
*hc
)
347 dsa_sigctx
*ds
= dsa_doinit(k
, &dp
->dp
, dp
->y
, hc
, group_binary
, "binary");
348 ds
->g
.u
= MP_COPY(dp
->x
);
352 static sig
*ecdsa_siginit(key
*k
, void *kd
, const gchash
*hc
)
355 dsa_sigctx
*ds
= ecdsa_doinit(k
, ep
->cstr
, &ep
->p
, hc
);
356 ds
->g
.u
= MP_COPY(ep
->x
);
360 static int dsa_sigdoit(sig
*s
, dstr
*d
)
362 dsa_sigctx
*ds
= (dsa_sigctx
*)s
;
363 gdsa_sig ss
= GDSA_SIG_INIT
;
364 size_t n
= mp_octets(ds
->g
.g
->r
);
366 gdsa_sign(&ds
->g
, &ss
, GH_DONE(ds
->s
.h
, 0), 0);
367 dstr_ensure(d
, 2 * n
);
368 mp_storeb(ss
.r
, d
->buf
, n
);
369 mp_storeb(ss
.s
, d
->buf
+ n
, n
);
371 mp_drop(ss
.r
); mp_drop(ss
.s
);
375 static const char *dsa_sigcheck(sig
*s
)
377 dsa_sigctx
*ds
= (dsa_sigctx
*)s
;
379 if ((e
= G_CHECK(ds
->g
.g
, &rand_global
)) != 0)
381 if (group_check(ds
->g
.g
, ds
->g
.p
))
382 return ("public key not in subgroup");
386 static void dsa_sigdestroy(sig
*s
)
388 dsa_sigctx
*ds
= (dsa_sigctx
*)s
;
389 G_DESTROY(ds
->g
.g
, ds
->g
.p
);
391 G_DESTROYGROUP(ds
->g
.g
);
395 static const sigops dsa_sig
= {
396 dh_privfetch
, sizeof(dh_priv
),
397 dsa_siginit
, dsa_sigdoit
, dsa_sigcheck
, dsa_sigdestroy
400 static const sigops bindsa_sig
= {
401 dh_privfetch
, sizeof(dh_priv
),
402 bindsa_siginit
, dsa_sigdoit
, dsa_sigcheck
, dsa_sigdestroy
405 static const sigops ecdsa_sig
= {
406 ec_privfetch
, sizeof(ec_priv
),
407 ecdsa_siginit
, dsa_sigdoit
, dsa_sigcheck
, dsa_sigdestroy
410 static sig
*dsa_vrfinit(key
*k
, void *kd
, const gchash
*hc
)
413 dsa_sigctx
*ds
= dsa_doinit(k
, &dp
->dp
, dp
->y
, hc
, group_prime
, "prime");
417 static sig
*bindsa_vrfinit(key
*k
, void *kd
, const gchash
*hc
)
420 dsa_sigctx
*ds
= dsa_doinit(k
, &dp
->dp
, dp
->y
, hc
, group_binary
, "binary");
424 static sig
*ecdsa_vrfinit(key
*k
, void *kd
, const gchash
*hc
)
427 dsa_sigctx
*ds
= ecdsa_doinit(k
, ep
->cstr
, &ep
->p
, hc
);
431 static int dsa_vrfdoit(sig
*s
, dstr
*d
)
433 dsa_sigctx
*ds
= (dsa_sigctx
*)s
;
438 ss
.r
= mp_loadb(MP_NEW
, d
->buf
, n
);
439 ss
.s
= mp_loadb(MP_NEW
, d
->buf
+ n
, d
->len
- n
);
440 rc
= gdsa_verify(&ds
->g
, &ss
, GH_DONE(ds
->s
.h
, 0));
441 mp_drop(ss
.r
); mp_drop(ss
.s
);
445 static const sigops dsa_vrf
= {
446 dh_pubfetch
, sizeof(dh_pub
),
447 dsa_vrfinit
, dsa_vrfdoit
, dsa_sigcheck
, dsa_sigdestroy
450 static const sigops bindsa_vrf
= {
451 dh_pubfetch
, sizeof(dh_pub
),
452 bindsa_vrfinit
, dsa_vrfdoit
, dsa_sigcheck
, dsa_sigdestroy
455 static const sigops ecdsa_vrf
= {
456 ec_pubfetch
, sizeof(ec_pub
),
457 ecdsa_vrfinit
, dsa_vrfdoit
, dsa_sigcheck
, dsa_sigdestroy
460 /* --- KCDSA and ECKCDSA --- */
462 static void kcdsa_privkey(dsa_sigctx
*ds
, mp
*x
)
463 { ds
->g
.u
= mp_modinv(MP_NEW
, x
, ds
->g
.g
->r
); }
465 static void kcdsa_sethash(dsa_sigctx
*ds
, const gchash
*hc
)
466 { ds
->s
.h
= gkcdsa_beginhash(&ds
->g
); }
468 static sig
*kcdsa_siginit(key
*k
, void *kd
, const gchash
*hc
)
471 dsa_sigctx
*ds
= dsa_doinit(k
, &dp
->dp
, dp
->y
, hc
, group_prime
, "prime");
472 kcdsa_privkey(ds
, dp
->x
);
473 kcdsa_sethash(ds
, hc
);
477 static sig
*binkcdsa_siginit(key
*k
, void *kd
, const gchash
*hc
)
480 dsa_sigctx
*ds
= dsa_doinit(k
, &dp
->dp
, dp
->y
, hc
, group_binary
, "binary");
481 kcdsa_privkey(ds
, dp
->x
);
482 kcdsa_sethash(ds
, hc
);
486 static sig
*eckcdsa_siginit(key
*k
, void *kd
, const gchash
*hc
)
489 dsa_sigctx
*ds
= ecdsa_doinit(k
, ep
->cstr
, &ep
->p
, hc
);
490 kcdsa_privkey(ds
, ep
->x
);
491 kcdsa_sethash(ds
, hc
);
495 static int kcdsa_sigdoit(sig
*s
, dstr
*d
)
497 dsa_sigctx
*ds
= (dsa_sigctx
*)s
;
498 gkcdsa_sig ss
= GKCDSA_SIG_INIT
;
499 size_t hsz
= ds
->g
.h
->hashsz
, n
= mp_octets(ds
->g
.g
->r
);
501 gkcdsa_sign(&ds
->g
, &ss
, GH_DONE(ds
->s
.h
, 0), 0);
502 dstr_ensure(d
, hsz
+ n
);
503 memcpy(d
->buf
, ss
.r
, hsz
);
504 mp_storeb(ss
.s
, d
->buf
+ hsz
, n
);
506 xfree(ss
.r
); mp_drop(ss
.s
);
510 static const sigops kcdsa_sig
= {
511 dh_privfetch
, sizeof(dh_priv
),
512 kcdsa_siginit
, kcdsa_sigdoit
, dsa_sigcheck
, dsa_sigdestroy
515 static const sigops binkcdsa_sig
= {
516 dh_privfetch
, sizeof(dh_priv
),
517 binkcdsa_siginit
, kcdsa_sigdoit
, dsa_sigcheck
, dsa_sigdestroy
520 static const sigops eckcdsa_sig
= {
521 ec_privfetch
, sizeof(ec_priv
),
522 eckcdsa_siginit
, kcdsa_sigdoit
, dsa_sigcheck
, dsa_sigdestroy
525 static sig
*kcdsa_vrfinit(key
*k
, void *kd
, const gchash
*hc
)
528 dsa_sigctx
*ds
= dsa_doinit(k
, &dp
->dp
, dp
->y
, hc
, group_prime
, "prime");
529 kcdsa_sethash(ds
, hc
);
533 static sig
*binkcdsa_vrfinit(key
*k
, void *kd
, const gchash
*hc
)
536 dsa_sigctx
*ds
= dsa_doinit(k
, &dp
->dp
, dp
->y
, hc
, group_binary
, "binary");
537 kcdsa_sethash(ds
, hc
);
541 static sig
*eckcdsa_vrfinit(key
*k
, void *kd
, const gchash
*hc
)
544 dsa_sigctx
*ds
= ecdsa_doinit(k
, ep
->cstr
, &ep
->p
, hc
);
545 kcdsa_sethash(ds
, hc
);
549 static int kcdsa_vrfdoit(sig
*s
, dstr
*d
)
551 dsa_sigctx
*ds
= (dsa_sigctx
*)s
;
553 size_t hsz
= ds
->g
.h
->hashsz
, n
= d
->len
- hsz
;
558 ss
.r
= (octet
*)d
->buf
;
559 ss
.s
= mp_loadb(MP_NEW
, d
->buf
+ hsz
, n
);
560 rc
= gkcdsa_verify(&ds
->g
, &ss
, GH_DONE(ds
->s
.h
, 0));
565 static const sigops kcdsa_vrf
= {
566 dh_pubfetch
, sizeof(dh_pub
),
567 kcdsa_vrfinit
, kcdsa_vrfdoit
, dsa_sigcheck
, dsa_sigdestroy
570 static const sigops binkcdsa_vrf
= {
571 dh_pubfetch
, sizeof(dh_pub
),
572 binkcdsa_vrfinit
, kcdsa_vrfdoit
, dsa_sigcheck
, dsa_sigdestroy
575 static const sigops eckcdsa_vrf
= {
576 ec_pubfetch
, sizeof(ec_pub
),
577 eckcdsa_vrfinit
, kcdsa_vrfdoit
, dsa_sigcheck
, dsa_sigdestroy
583 _(ed25519, ed25519ctx, ED25519, "Ed25519", sha512) \
584 _(ed448, ed448, ED448, "Ed448", shake256)
586 typedef struct eddsa_sigctx
{
591 static sig
*eddsa_siginit(key
*k
, void *kd
, const gchash
*hc
)
593 eddsa_sigctx
*es
= CREATE(eddsa_sigctx
);
595 es
->perso
= key_getattr(0, k
, "perso");
596 if (es
->perso
&& strlen(es
->perso
) > ED25519_MAXPERSOSZ
) {
597 die(1, "EdDSA personalization string too long (max length %d)",
603 static void eddsa_sigdestroy(sig
*s
)
604 { eddsa_sigctx
*es
= (eddsa_sigctx
*)s
; DESTROY(es
); }
606 #define EDDSADEF(ed, sigver, ED, name, hash) \
608 static int ed##_sigdoit(sig *s, dstr *d) \
610 eddsa_sigctx *es = (eddsa_sigctx *)s; \
611 ed##_priv *k = es->s.kd; \
613 dstr_ensure(d, ED##_SIGSZ); \
614 sigver##_sign((octet *)d->buf, k->priv.k, k->priv.sz, k->pub.k, \
615 es->perso ? 1 : -1, es->perso, \
616 es->perso ? strlen(es->perso) : 0, \
617 GH_DONE(es->s.h, 0), GH_CLASS(es->s.h)->hashsz); \
618 d->len += ED##_SIGSZ; \
622 static const char *ed##_sigcheck(sig *s) \
624 eddsa_sigctx *es = (eddsa_sigctx *)s; \
625 ed##_priv *k = es->s.kd; \
627 if (k->pub.sz != ED##_PUBSZ) \
628 return ("incorrect " #name " public key length"); \
632 static const sigops ed##_sig = { \
633 ed##_privfetch, sizeof(ed##_priv), \
634 eddsa_siginit, ed##_sigdoit, ed##_sigcheck, eddsa_sigdestroy \
637 static int ed##_vrfdoit(sig *s, dstr *d) \
639 eddsa_sigctx *es = (eddsa_sigctx *)s; \
640 ed##_pub *k = es->s.kd; \
642 if (d->len != ED##_SIGSZ) return (-1); \
643 return (sigver##_verify(k->pub.k, \
644 es->perso ? 1 : -1, es->perso, \
645 es->perso ? strlen(es->perso) : 0, \
646 GH_DONE(s->h, 0), GH_CLASS(s->h)->hashsz, \
647 (const octet *)d->buf)); \
650 static const char *ed##_vrfcheck(sig *s) \
652 ed##_pub *k = s->kd; \
654 if (k->pub.sz != ED##_PUBSZ) \
655 return ("incorrect " #name " public key length"); \
659 static const sigops ed##_vrf = { \
660 ed##_pubfetch, sizeof(ed##_pub), \
661 eddsa_siginit, ed##_vrfdoit, ed##_vrfcheck, eddsa_sigdestroy \
667 /* --- Symmetric message authentication --- */
669 typedef struct mac_ctx
{
677 static sig
*mac_init(key
*k
, void *kd
, const gchash
*hc
)
687 m
->kp
.e
= KENC_BINARY
;
691 if ((mm
= key_getattr(0 /*yik*/, k
, "mac")) == 0) {
692 dstr_putf(&d
, "%s-hmac", hc
->name
);
695 if ((m
->mc
= gmac_byname(mm
)) == 0)
696 die(EXIT_FAILURE
, "unknown message authentication scheme `%s'", mm
);
699 if ((err
= key_unpack(&m
->kp
, kd
, &d
)) != 0) {
700 die(EXIT_FAILURE
, "failed to unpack symmetric key `%s': %s",
701 d
.buf
, key_strerror(err
));
705 if (keysz(m
->kb
.sz
, m
->mc
->keysz
) != m
->kb
.sz
) {
706 die(EXIT_FAILURE
, "bad key size %lu for `%s'",
707 (unsigned long)m
->kb
.sz
, m
->mc
->name
);
709 m
->m
= GM_KEY(m
->mc
, m
->kb
.k
, m
->kb
.sz
);
710 m
->s
.h
= GM_INIT(m
->m
);
714 static int mac_sigdoit(sig
*s
, dstr
*d
)
716 mac_ctx
*m
= (mac_ctx
*)s
;
718 dstr_ensure(d
, m
->mc
->hashsz
);
719 GH_DONE(m
->s
.h
, d
->buf
);
720 d
->len
+= m
->mc
->hashsz
;
724 static int mac_vrfdoit(sig
*s
, dstr
*d
)
726 mac_ctx
*m
= (mac_ctx
*)s
;
729 t
= GH_DONE(m
->s
.h
, 0);
730 if (d
->len
!= m
->mc
->hashsz
|| !ct_memeq(d
->buf
, t
, d
->len
))
735 static const char *mac_check(sig
*s
) { return (0); }
737 static void mac_destroy(sig
*s
)
739 mac_ctx
*m
= (mac_ctx
*)s
;
741 key_unpackdone(&m
->kp
);
744 static const sigops mac_sig
= {
746 mac_init
, mac_sigdoit
, mac_check
, mac_destroy
749 static const sigops mac_vrf
= {
751 mac_init
, mac_vrfdoit
, mac_check
, mac_destroy
754 /* --- The switch table --- */
756 const struct sigtab sigtab
[] = {
757 { "rsapkcs1", &rsap1_sig
, &rsap1_vrf
, &sha
},
758 { "rsapss", &rsapss_sig
, &rsapss_vrf
, &sha
},
759 { "dsa", &dsa_sig
, &dsa_vrf
, &sha
},
760 { "bindsa", &bindsa_sig
, &bindsa_vrf
, &sha
},
761 { "ecdsa", &ecdsa_sig
, &ecdsa_vrf
, &sha
},
762 { "kcdsa", &kcdsa_sig
, &kcdsa_vrf
, &has160
},
763 { "binkcdsa", &binkcdsa_sig
, &binkcdsa_vrf
, &has160
},
764 { "eckcdsa", &eckcdsa_sig
, &eckcdsa_vrf
, &has160
},
765 #define EDDSATAB(ed, sigver, ED, name, hash) \
766 { #ed, &ed##_sig, &ed##_vrf, &hash },
769 { "mac", &mac_sig
, &mac_vrf
, &rmd160
},
773 /* --- @getsig@ --- *
775 * Arguments: @key *k@ = the key to load
776 * @const char *app@ = application name
777 * @int wantpriv@ = nonzero if we want to sign
779 * Returns: A signature-making thing.
781 * Use: Loads a key and starts hashing.
784 sig
*getsig(key
*k
, const char *app
, int wantpriv
)
786 const char *salg
, *halg
= 0;
793 const struct sigtab
*st
;
800 /* --- Setup stuff --- */
804 /* --- Get the signature algorithm --- *
806 * Take the attribute if it's there; otherwise use the key type.
810 if ((q
= key_getattr(0, k
, "sig")) != 0) {
813 } else if (STRNCMP(k
->type
, ==, app
, n
) && k
->type
[n
] == '-') {
814 dstr_puts(&d
, k
->type
);
817 die(EXIT_FAILURE
, "no signature algorithm for key `%s'", t
.buf
);
819 /* --- Grab the hash algorithm --- *
821 * Grab it from the signature algorithm if it's there. But override that
822 * from the attribute.
826 if ((p
= strchr(p
, '/')) != 0) {
830 if ((q
= key_getattr(0, k
, "hash")) != 0)
833 /* --- Look up the algorithms in the table --- */
835 for (st
= sigtab
; st
->name
; st
++) {
836 if (STRCMP(st
->name
, ==, salg
))
839 die(EXIT_FAILURE
, "signature algorithm `%s' not found in key `%s'",
845 if ((ch
= ghash_byname(halg
)) == 0) {
846 die(EXIT_FAILURE
, "hash algorithm `%s' not found in key `%s'",
850 so
= wantpriv ? st
->signops
: st
->verifyops
;
852 /* --- Load the key --- */
859 kd
= xmalloc(so
->kdsz
);
860 kp
= key_fetchinit(so
->kf
, 0, kd
);
861 if ((e
= key_fetch(kp
, k
)) != 0) {
862 die(EXIT_FAILURE
, "error fetching key `%s': %s",
863 t
.buf
, key_strerror(e
));
866 s
= so
->init(k
, kd
, ch
);
874 /* --- Free stuff up --- */
881 /* --- @freesig@ --- *
883 * Arguments: @sig *s@ = signature-making thing
887 * Use: Frees up a signature-making thing
896 key_fetchdone(s
->kp
);
902 /*----- That's all, folks -------------------------------------------------*/