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/report.h>
52 /*----- Main code ---------------------------------------------------------*/
54 /* --- RSA PKCS1 --- */
56 typedef struct rsap1_sigctx
{
62 static sig
*rsap1_siginit(key
*k
, void *kd
, const gchash
*hc
)
64 rsap1_sigctx
*rs
= CREATE(rsap1_sigctx
);
65 rsa_privcreate(&rs
->rp
, kd
, &rand_global
);
66 rs
->p1
.r
= &rand_global
;
68 rs
->p1
.epsz
= strlen(hc
->name
) + 1;
73 static int rsap1_sigdoit(sig
*s
, dstr
*d
)
75 rsap1_sigctx
*rs
= (rsap1_sigctx
*)s
;
77 mp
*m
= rsa_sign(&rs
->rp
, MP_NEW
,
78 GH_DONE(s
->h
, 0), GH_CLASS(s
->h
)->hashsz
,
79 pkcs1_sigencode
, &rs
->p1
);
81 n
= mp_octets(rs
->rp
.rp
->n
); dstr_ensure(d
, n
); mp_storeb(m
, d
->buf
, n
);
82 d
->len
+= n
; mp_drop(m
);
86 static const char *rsa_lengthcheck(mp
*n
)
88 if (mp_bits(n
) < 1024) return ("key too short");
92 static const char *rsap1_sigcheck(sig
*s
)
94 rsap1_sigctx
*rs
= (rsap1_sigctx
*)s
;
96 if ((e
= rsa_lengthcheck(rs
->rp
.rp
->n
)) != 0) return (e
);
100 static void rsap1_sigdestroy(sig
*s
)
102 rsap1_sigctx
*rs
= (rsap1_sigctx
*)s
;
103 rsa_privdestroy(&rs
->rp
);
107 static const sigops rsap1_sig
= {
108 rsa_privfetch
, sizeof(rsa_priv
),
109 rsap1_siginit
, rsap1_sigdoit
, rsap1_sigcheck
, rsap1_sigdestroy
112 typedef struct rsap1_vrfctx
{
118 static sig
*rsap1_vrfinit(key
*k
, void *kd
, const gchash
*hc
)
120 rsap1_vrfctx
*rv
= CREATE(rsap1_vrfctx
);
121 rsa_pubcreate(&rv
->rp
, kd
);
122 rv
->p1
.r
= &rand_global
;
123 rv
->p1
.ep
= hc
->name
;
124 rv
->p1
.epsz
= strlen(hc
->name
) + 1;
129 static int rsap1_vrfdoit(sig
*s
, dstr
*d
)
131 rsap1_vrfctx
*rv
= (rsap1_vrfctx
*)s
;
132 mp
*m
= mp_loadb(MP_NEW
, d
->buf
, d
->len
);
133 int rc
= rsa_verify(&rv
->rp
, m
,
134 GH_DONE(s
->h
, 0), GH_CLASS(s
->h
)->hashsz
,
135 0, pkcs1_sigdecode
, &rv
->p1
);
140 static const char *rsap1_vrfcheck(sig
*s
)
142 rsap1_vrfctx
*rv
= (rsap1_vrfctx
*)s
;
144 if ((e
= rsa_lengthcheck(rv
->rp
.rp
->n
)) != 0) return (e
);
148 static void rsap1_vrfdestroy(sig
*s
)
150 rsap1_vrfctx
*rv
= (rsap1_vrfctx
*)s
;
151 rsa_pubdestroy(&rv
->rp
);
155 static const sigops rsap1_vrf
= {
156 rsa_pubfetch
, sizeof(rsa_pub
),
157 rsap1_vrfinit
, rsap1_vrfdoit
, rsap1_vrfcheck
, rsap1_vrfdestroy
160 /* --- RSA PSS --- */
162 static const gccipher
*getmgf(key
*k
, const gchash
*hc
)
168 if ((mm
= key_getattr(0, k
, "mgf")) == 0) {
169 dstr_putf(&d
, "%s-mgf", hc
->name
);
172 if ((gc
= gcipher_byname(mm
)) == 0)
173 die(EXIT_FAILURE
, "unknown encryption scheme `%s'", mm
);
178 typedef struct rsapss_sigctx
{
184 static sig
*rsapss_siginit(key
*k
, void *kd
, const gchash
*hc
)
186 rsapss_sigctx
*rs
= CREATE(rsapss_sigctx
);
187 rsa_privcreate(&rs
->rp
, kd
, &rand_global
);
189 rs
->p
.r
= &rand_global
;
190 rs
->p
.cc
= getmgf(k
, hc
);
192 rs
->p
.ssz
= hc
->hashsz
;
196 static int rsapss_sigdoit(sig
*s
, dstr
*d
)
198 rsapss_sigctx
*rs
= (rsapss_sigctx
*)s
;
200 mp
*m
= rsa_sign(&rs
->rp
, MP_NEW
,
201 GH_DONE(s
->h
, 0), GH_CLASS(s
->h
)->hashsz
,
204 n
= mp_octets(rs
->rp
.rp
->n
); dstr_ensure(d
, n
); mp_storeb(m
, d
->buf
, n
);
205 d
->len
+= n
; mp_drop(m
);
209 static const char *rsapss_sigcheck(sig
*s
)
211 rsapss_sigctx
*rs
= (rsapss_sigctx
*)s
;
213 if ((e
= rsa_lengthcheck(rs
->rp
.rp
->n
)) != 0) return (e
);
217 static void rsapss_sigdestroy(sig
*s
)
219 rsapss_sigctx
*rs
= (rsapss_sigctx
*)s
;
220 rsa_privdestroy(&rs
->rp
);
224 static const sigops rsapss_sig
= {
225 rsa_privfetch
, sizeof(rsa_priv
),
226 rsapss_siginit
, rsapss_sigdoit
, rsapss_sigcheck
, rsapss_sigdestroy
229 typedef struct rsapss_vrfctx
{
235 static sig
*rsapss_vrfinit(key
*k
, void *kd
, const gchash
*hc
)
237 rsapss_vrfctx
*rv
= CREATE(rsapss_vrfctx
);
238 rsa_pubcreate(&rv
->rp
, kd
);
240 rv
->p
.r
= &rand_global
;
241 rv
->p
.cc
= getmgf(k
, hc
);
243 rv
->p
.ssz
= hc
->hashsz
;
247 static int rsapss_vrfdoit(sig
*s
, dstr
*d
)
249 rsapss_vrfctx
*rv
= (rsapss_vrfctx
*)s
;
250 mp
*m
= mp_loadb(MP_NEW
, d
->buf
, d
->len
);
251 int rc
= rsa_verify(&rv
->rp
, m
,
252 GH_DONE(s
->h
, 0), GH_CLASS(s
->h
)->hashsz
,
253 0, pss_decode
, &rv
->p
);
258 static const char *rsapss_vrfcheck(sig
*s
)
260 rsapss_vrfctx
*rv
= (rsapss_vrfctx
*)s
;
262 if ((e
= rsa_lengthcheck(rv
->rp
.rp
->n
)) != 0) return (e
);
266 static void rsapss_vrfdestroy(sig
*s
)
268 rsapss_vrfctx
*rv
= (rsapss_vrfctx
*)s
;
269 rsa_pubdestroy(&rv
->rp
);
273 static const sigops rsapss_vrf
= {
274 rsa_pubfetch
, sizeof(rsa_pub
),
275 rsapss_vrfinit
, rsapss_vrfdoit
, rsapss_vrfcheck
, rsapss_vrfdestroy
278 /* --- DSA and ECDSA --- */
280 typedef struct dsa_sigctx
{
285 static void dsa_initcommon(dsa_sigctx
*ds
, const gchash
*hc
,
288 ds
->g
.r
= &rand_global
;
294 static dsa_sigctx
*dsa_doinit(key
*k
, const gprime_param
*gp
,
295 mp
*y
, const gchash
*hc
,
296 group
*(*makegroup
)(const gprime_param
*),
299 dsa_sigctx
*ds
= CREATE(dsa_sigctx
);
303 if ((ds
->g
.g
= makegroup(gp
)) == 0)
304 die(EXIT_FAILURE
, "bad %s group in key `%s'", what
, t
.buf
);
305 ds
->g
.p
= G_CREATE(ds
->g
.g
);
306 if (G_FROMINT(ds
->g
.g
, ds
->g
.p
, y
))
307 die(EXIT_FAILURE
, "bad public key in key `%s'", t
.buf
);
308 dsa_initcommon(ds
, hc
, t
.buf
);
313 static dsa_sigctx
*ecdsa_doinit(key
*k
, const char *cstr
,
314 ec
*y
, const gchash
*hc
)
316 dsa_sigctx
*ds
= CREATE(dsa_sigctx
);
322 if ((e
= ec_getinfo(&ei
, cstr
)) != 0)
323 die(EXIT_FAILURE
, "bad curve in key `%s': %s", t
.buf
, e
);
324 ds
->g
.g
= group_ec(&ei
);
325 ds
->g
.p
= G_CREATE(ds
->g
.g
);
326 if (G_FROMEC(ds
->g
.g
, ds
->g
.p
, y
))
327 die(EXIT_FAILURE
, "bad public key in key `%s'", t
.buf
);
328 dsa_initcommon(ds
, hc
, t
.buf
);
333 static sig
*dsa_siginit(key
*k
, void *kd
, const gchash
*hc
)
336 dsa_sigctx
*ds
= dsa_doinit(k
, &dp
->dp
, dp
->y
, hc
, group_prime
, "prime");
337 ds
->g
.u
= MP_COPY(dp
->x
);
341 static sig
*bindsa_siginit(key
*k
, void *kd
, const gchash
*hc
)
344 dsa_sigctx
*ds
= dsa_doinit(k
, &dp
->dp
, dp
->y
, hc
, group_binary
, "binary");
345 ds
->g
.u
= MP_COPY(dp
->x
);
349 static sig
*ecdsa_siginit(key
*k
, void *kd
, const gchash
*hc
)
352 dsa_sigctx
*ds
= ecdsa_doinit(k
, ep
->cstr
, &ep
->p
, hc
);
353 ds
->g
.u
= MP_COPY(ep
->x
);
357 static int dsa_sigdoit(sig
*s
, dstr
*d
)
359 dsa_sigctx
*ds
= (dsa_sigctx
*)s
;
360 gdsa_sig ss
= GDSA_SIG_INIT
;
361 size_t n
= mp_octets(ds
->g
.g
->r
);
363 gdsa_sign(&ds
->g
, &ss
, GH_DONE(ds
->s
.h
, 0), 0);
364 dstr_ensure(d
, 2 * n
);
365 mp_storeb(ss
.r
, d
->buf
, n
);
366 mp_storeb(ss
.s
, d
->buf
+ n
, n
);
368 mp_drop(ss
.r
); mp_drop(ss
.s
);
372 static const char *dsa_sigcheck(sig
*s
)
374 dsa_sigctx
*ds
= (dsa_sigctx
*)s
;
376 if ((e
= G_CHECK(ds
->g
.g
, &rand_global
)) != 0)
378 if (group_check(ds
->g
.g
, ds
->g
.p
))
379 return ("public key not in subgroup");
383 static void dsa_sigdestroy(sig
*s
)
385 dsa_sigctx
*ds
= (dsa_sigctx
*)s
;
386 G_DESTROY(ds
->g
.g
, ds
->g
.p
);
388 G_DESTROYGROUP(ds
->g
.g
);
392 static const sigops dsa_sig
= {
393 dh_privfetch
, sizeof(dh_priv
),
394 dsa_siginit
, dsa_sigdoit
, dsa_sigcheck
, dsa_sigdestroy
397 static const sigops bindsa_sig
= {
398 dh_privfetch
, sizeof(dh_priv
),
399 bindsa_siginit
, dsa_sigdoit
, dsa_sigcheck
, dsa_sigdestroy
402 static const sigops ecdsa_sig
= {
403 ec_privfetch
, sizeof(ec_priv
),
404 ecdsa_siginit
, dsa_sigdoit
, dsa_sigcheck
, dsa_sigdestroy
407 static sig
*dsa_vrfinit(key
*k
, void *kd
, const gchash
*hc
)
410 dsa_sigctx
*ds
= dsa_doinit(k
, &dp
->dp
, dp
->y
, hc
, group_prime
, "prime");
414 static sig
*bindsa_vrfinit(key
*k
, void *kd
, const gchash
*hc
)
417 dsa_sigctx
*ds
= dsa_doinit(k
, &dp
->dp
, dp
->y
, hc
, group_binary
, "binary");
421 static sig
*ecdsa_vrfinit(key
*k
, void *kd
, const gchash
*hc
)
424 dsa_sigctx
*ds
= ecdsa_doinit(k
, ep
->cstr
, &ep
->p
, hc
);
428 static int dsa_vrfdoit(sig
*s
, dstr
*d
)
430 dsa_sigctx
*ds
= (dsa_sigctx
*)s
;
435 ss
.r
= mp_loadb(MP_NEW
, d
->buf
, n
);
436 ss
.s
= mp_loadb(MP_NEW
, d
->buf
+ n
, d
->len
- n
);
437 rc
= gdsa_verify(&ds
->g
, &ss
, GH_DONE(ds
->s
.h
, 0));
438 mp_drop(ss
.r
); mp_drop(ss
.s
);
442 static const sigops dsa_vrf
= {
443 dh_pubfetch
, sizeof(dh_pub
),
444 dsa_vrfinit
, dsa_vrfdoit
, dsa_sigcheck
, dsa_sigdestroy
447 static const sigops bindsa_vrf
= {
448 dh_pubfetch
, sizeof(dh_pub
),
449 bindsa_vrfinit
, dsa_vrfdoit
, dsa_sigcheck
, dsa_sigdestroy
452 static const sigops ecdsa_vrf
= {
453 ec_pubfetch
, sizeof(ec_pub
),
454 ecdsa_vrfinit
, dsa_vrfdoit
, dsa_sigcheck
, dsa_sigdestroy
457 /* --- KCDSA and ECKCDSA --- */
459 static void kcdsa_privkey(dsa_sigctx
*ds
, mp
*x
)
460 { ds
->g
.u
= mp_modinv(MP_NEW
, x
, ds
->g
.g
->r
); }
462 static void kcdsa_sethash(dsa_sigctx
*ds
, const gchash
*hc
)
463 { ds
->s
.h
= gkcdsa_beginhash(&ds
->g
); }
465 static sig
*kcdsa_siginit(key
*k
, void *kd
, const gchash
*hc
)
468 dsa_sigctx
*ds
= dsa_doinit(k
, &dp
->dp
, dp
->y
, hc
, group_prime
, "prime");
469 kcdsa_privkey(ds
, dp
->x
);
470 kcdsa_sethash(ds
, hc
);
474 static sig
*binkcdsa_siginit(key
*k
, void *kd
, const gchash
*hc
)
477 dsa_sigctx
*ds
= dsa_doinit(k
, &dp
->dp
, dp
->y
, hc
, group_binary
, "binary");
478 kcdsa_privkey(ds
, dp
->x
);
479 kcdsa_sethash(ds
, hc
);
483 static sig
*eckcdsa_siginit(key
*k
, void *kd
, const gchash
*hc
)
486 dsa_sigctx
*ds
= ecdsa_doinit(k
, ep
->cstr
, &ep
->p
, hc
);
487 kcdsa_privkey(ds
, ep
->x
);
488 kcdsa_sethash(ds
, hc
);
492 static int kcdsa_sigdoit(sig
*s
, dstr
*d
)
494 dsa_sigctx
*ds
= (dsa_sigctx
*)s
;
495 gkcdsa_sig ss
= GKCDSA_SIG_INIT
;
496 size_t hsz
= ds
->g
.h
->hashsz
, n
= mp_octets(ds
->g
.g
->r
);
498 gkcdsa_sign(&ds
->g
, &ss
, GH_DONE(ds
->s
.h
, 0), 0);
499 dstr_ensure(d
, hsz
+ n
);
500 memcpy(d
->buf
, ss
.r
, hsz
);
501 mp_storeb(ss
.s
, d
->buf
+ hsz
, n
);
503 xfree(ss
.r
); mp_drop(ss
.s
);
507 static const sigops kcdsa_sig
= {
508 dh_privfetch
, sizeof(dh_priv
),
509 kcdsa_siginit
, kcdsa_sigdoit
, dsa_sigcheck
, dsa_sigdestroy
512 static const sigops binkcdsa_sig
= {
513 dh_privfetch
, sizeof(dh_priv
),
514 binkcdsa_siginit
, kcdsa_sigdoit
, dsa_sigcheck
, dsa_sigdestroy
517 static const sigops eckcdsa_sig
= {
518 ec_privfetch
, sizeof(ec_priv
),
519 eckcdsa_siginit
, kcdsa_sigdoit
, dsa_sigcheck
, dsa_sigdestroy
522 static sig
*kcdsa_vrfinit(key
*k
, void *kd
, const gchash
*hc
)
525 dsa_sigctx
*ds
= dsa_doinit(k
, &dp
->dp
, dp
->y
, hc
, group_prime
, "prime");
526 kcdsa_sethash(ds
, hc
);
530 static sig
*binkcdsa_vrfinit(key
*k
, void *kd
, const gchash
*hc
)
533 dsa_sigctx
*ds
= dsa_doinit(k
, &dp
->dp
, dp
->y
, hc
, group_binary
, "binary");
534 kcdsa_sethash(ds
, hc
);
538 static sig
*eckcdsa_vrfinit(key
*k
, void *kd
, const gchash
*hc
)
541 dsa_sigctx
*ds
= ecdsa_doinit(k
, ep
->cstr
, &ep
->p
, hc
);
542 kcdsa_sethash(ds
, hc
);
546 static int kcdsa_vrfdoit(sig
*s
, dstr
*d
)
548 dsa_sigctx
*ds
= (dsa_sigctx
*)s
;
550 size_t hsz
= ds
->g
.h
->hashsz
, n
= d
->len
- hsz
;
555 ss
.r
= (octet
*)d
->buf
;
556 ss
.s
= mp_loadb(MP_NEW
, d
->buf
+ hsz
, n
);
557 rc
= gkcdsa_verify(&ds
->g
, &ss
, GH_DONE(ds
->s
.h
, 0));
562 static const sigops kcdsa_vrf
= {
563 dh_pubfetch
, sizeof(dh_pub
),
564 kcdsa_vrfinit
, kcdsa_vrfdoit
, dsa_sigcheck
, dsa_sigdestroy
567 static const sigops binkcdsa_vrf
= {
568 dh_pubfetch
, sizeof(dh_pub
),
569 binkcdsa_vrfinit
, kcdsa_vrfdoit
, dsa_sigcheck
, dsa_sigdestroy
572 static const sigops eckcdsa_vrf
= {
573 ec_pubfetch
, sizeof(ec_pub
),
574 eckcdsa_vrfinit
, kcdsa_vrfdoit
, dsa_sigcheck
, dsa_sigdestroy
577 /* --- Ed25519 --- */
579 static sig
*ed25519_siginit(key
*k
, void *kd
, const gchash
*hc
)
580 { sig
*s
= CREATE(sig
); s
->h
= 0; return (s
); }
582 static int ed25519_sigdoit(sig
*s
, dstr
*d
)
584 ed25519_priv
*k
= s
->kd
;
586 dstr_ensure(d
, ED25519_SIGSZ
);
587 ed25519_sign((octet
*)d
->buf
, k
->priv
.k
, k
->priv
.sz
, k
->pub
.k
,
588 GH_DONE(s
->h
, 0), GH_CLASS(s
->h
)->hashsz
);
589 d
->len
+= ED25519_SIGSZ
;
593 static const char *ed25519_sigcheck(sig
*s
)
595 ed25519_priv
*k
= s
->kd
;
597 if (k
->pub
.sz
!= ED25519_PUBSZ
)
598 return ("incorrect Ed25519 public key length");
602 static void ed25519_sigdestroy(sig
*s
) { DESTROY(s
); }
604 static const sigops ed25519_sig
= {
605 ed25519_privfetch
, sizeof(ed25519_priv
),
606 ed25519_siginit
, ed25519_sigdoit
, ed25519_sigcheck
, ed25519_sigdestroy
609 static int ed25519_vrfdoit(sig
*s
, dstr
*d
)
611 ed25519_pub
*k
= s
->kd
;
613 if (d
->len
!= ED25519_SIGSZ
) return (-1);
614 return (ed25519_verify(k
->pub
.k
, GH_DONE(s
->h
, 0), GH_CLASS(s
->h
)->hashsz
,
615 (const octet
*)d
->buf
));
618 static const char *ed25519_vrfcheck(sig
*s
)
620 ed25519_pub
*k
= s
->kd
;
622 if (k
->pub
.sz
!= ED25519_PUBSZ
)
623 return ("incorrect Ed25519 public key length");
627 static const sigops ed25519_vrf
= {
628 ed25519_pubfetch
, sizeof(ed25519_pub
),
629 ed25519_siginit
, ed25519_vrfdoit
, ed25519_vrfcheck
, ed25519_sigdestroy
632 /* --- Symmetric message authentication --- */
634 typedef struct mac_ctx
{
642 static sig
*mac_init(key
*k
, void *kd
, const gchash
*hc
)
652 m
->kp
.e
= KENC_BINARY
;
656 if ((mm
= key_getattr(0 /*yik*/, k
, "mac")) == 0) {
657 dstr_putf(&d
, "%s-hmac", hc
->name
);
660 if ((m
->mc
= gmac_byname(mm
)) == 0)
661 die(EXIT_FAILURE
, "unknown message authentication scheme `%s'", mm
);
664 if ((err
= key_unpack(&m
->kp
, kd
, &d
)) != 0) {
665 die(EXIT_FAILURE
, "failed to unpack symmetric key `%s': %s",
666 d
.buf
, key_strerror(err
));
670 if (keysz(m
->kb
.sz
, m
->mc
->keysz
) != m
->kb
.sz
) {
671 die(EXIT_FAILURE
, "bad key size %lu for `%s'",
672 (unsigned long)m
->kb
.sz
, m
->mc
->name
);
674 m
->m
= GM_KEY(m
->mc
, m
->kb
.k
, m
->kb
.sz
);
675 m
->s
.h
= GM_INIT(m
->m
);
679 static int mac_sigdoit(sig
*s
, dstr
*d
)
681 mac_ctx
*m
= (mac_ctx
*)s
;
683 dstr_ensure(d
, m
->mc
->hashsz
);
684 GH_DONE(m
->s
.h
, d
->buf
);
685 d
->len
+= m
->mc
->hashsz
;
689 static int mac_vrfdoit(sig
*s
, dstr
*d
)
691 mac_ctx
*m
= (mac_ctx
*)s
;
694 t
= GH_DONE(m
->s
.h
, 0);
695 if (d
->len
!= m
->mc
->hashsz
|| !ct_memeq(d
->buf
, t
, d
->len
))
700 static const char *mac_check(sig
*s
) { return (0); }
702 static void mac_destroy(sig
*s
)
704 mac_ctx
*m
= (mac_ctx
*)s
;
706 key_unpackdone(&m
->kp
);
709 static const sigops mac_sig
= {
711 mac_init
, mac_sigdoit
, mac_check
, mac_destroy
714 static const sigops mac_vrf
= {
716 mac_init
, mac_vrfdoit
, mac_check
, mac_destroy
719 /* --- The switch table --- */
721 const struct sigtab sigtab
[] = {
722 { "rsapkcs1", &rsap1_sig
, &rsap1_vrf
, &sha
},
723 { "rsapss", &rsapss_sig
, &rsapss_vrf
, &sha
},
724 { "dsa", &dsa_sig
, &dsa_vrf
, &sha
},
725 { "bindsa", &bindsa_sig
, &bindsa_vrf
, &sha
},
726 { "ecdsa", &ecdsa_sig
, &ecdsa_vrf
, &sha
},
727 { "kcdsa", &kcdsa_sig
, &kcdsa_vrf
, &has160
},
728 { "binkcdsa", &binkcdsa_sig
, &binkcdsa_vrf
, &has160
},
729 { "eckcdsa", &eckcdsa_sig
, &eckcdsa_vrf
, &has160
},
730 { "ed25519", &ed25519_sig
, &ed25519_vrf
, &sha512
},
731 { "mac", &mac_sig
, &mac_vrf
, &rmd160
},
735 /* --- @getsig@ --- *
737 * Arguments: @key *k@ = the key to load
738 * @const char *app@ = application name
739 * @int wantpriv@ = nonzero if we want to sign
741 * Returns: A signature-making thing.
743 * Use: Loads a key and starts hashing.
746 sig
*getsig(key
*k
, const char *app
, int wantpriv
)
748 const char *salg
, *halg
= 0;
755 const struct sigtab
*st
;
762 /* --- Setup stuff --- */
766 /* --- Get the signature algorithm --- *
768 * Take the attribute if it's there; otherwise use the key type.
772 if ((q
= key_getattr(0, k
, "sig")) != 0) {
775 } else if (strncmp(k
->type
, app
, n
) == 0 && k
->type
[n
] == '-') {
776 dstr_puts(&d
, k
->type
);
779 die(EXIT_FAILURE
, "no signature algorithm for key `%s'", t
.buf
);
781 /* --- Grab the hash algorithm --- *
783 * Grab it from the signature algorithm if it's there. But override that
784 * from the attribute.
788 if ((p
= strchr(p
, '/')) != 0) {
792 if ((q
= key_getattr(0, k
, "hash")) != 0)
795 /* --- Look up the algorithms in the table --- */
797 for (st
= sigtab
; st
->name
; st
++) {
798 if (strcmp(st
->name
, salg
) == 0)
801 die(EXIT_FAILURE
, "signature algorithm `%s' not found in key `%s'",
807 if ((ch
= ghash_byname(halg
)) == 0) {
808 die(EXIT_FAILURE
, "hash algorithm `%s' not found in key `%s'",
812 so
= wantpriv ? st
->signops
: st
->verifyops
;
814 /* --- Load the key --- */
821 kd
= xmalloc(so
->kdsz
);
822 kp
= key_fetchinit(so
->kf
, 0, kd
);
823 if ((e
= key_fetch(kp
, k
)) != 0) {
824 die(EXIT_FAILURE
, "error fetching key `%s': %s",
825 t
.buf
, key_strerror(e
));
828 s
= so
->init(k
, kd
, ch
);
836 /* --- Free stuff up --- */
843 /* --- @freesig@ --- *
845 * Arguments: @sig *s@ = signature-making thing
849 * Use: Frees up a signature-making thing
858 key_fetchdone(s
->kp
);
864 /*----- That's all, folks -------------------------------------------------*/