Project

General

Profile

Statistics
| Branch: | Tag: | Revision:

gdp / ep / ep_crypto_sign.c @ master

History | View | Annotate | Download (4.18 KB)

1 f80ae9c0 Eric Allman
/* vim: set ai sw=8 sts=8 ts=8 : */
2
3 055d3009 Eric Allman
/***********************************************************************
4
**  ----- BEGIN LICENSE BLOCK -----
5
**        LIBEP: Enhanced Portability Library (Reduced Edition)
6
**
7 c87dd166 Eric Allman
**        Copyright (c) 2008-2019, Eric P. Allman.  All rights reserved.
8
**        Copyright (c) 2015-2019, Regents of the University of California.
9 6bd5476b Eric Allman
**        All rights reserved.
10 055d3009 Eric Allman
**
11 6bd5476b Eric Allman
**        Permission is hereby granted, without written agreement and without
12
**        license or royalty fees, to use, copy, modify, and distribute this
13
**        software and its documentation for any purpose, provided that the above
14
**        copyright notice and the following two paragraphs appear in all copies
15
**        of this software.
16 055d3009 Eric Allman
**
17 6bd5476b Eric Allman
**        IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
18
**        SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST
19
**        PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
20
**        EVEN IF REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21 055d3009 Eric Allman
**
22 6bd5476b Eric Allman
**        REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
23 055d3009 Eric Allman
**        LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 6bd5476b Eric Allman
**        FOR A PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION,
25
**        IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO
26
**        OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
27
**        OR MODIFICATIONS.
28 055d3009 Eric Allman
**  ----- END LICENSE BLOCK -----
29
***********************************************************************/
30
31 03834a8b Eric Allman
/*
32
**  Do cryptographic signatures
33
**
34
**        Note that the internal structure while computing a signature
35
**        is an EP_CRYPTO_MD; thus you may see a mix of calls to (for
36
**        example) ep_crypto_md_clone and ep_crypto_sign_final.
37
*/
38
39 f80ae9c0 Eric Allman
#include <ep/ep.h>
40 74920de3 Eric Allman
#include <ep/ep_crypto.h>
41
#include <ep/ep_dbg.h>
42 f80ae9c0 Eric Allman
43 74920de3 Eric Allman
static EP_DBG        Dbg = EP_DBG_INIT("libep.crypto.sign", "cryptographic signature generation");
44 f80ae9c0 Eric Allman
45 03834a8b Eric Allman
46
/*
47
**  Create a new signing context.  Note that this returns a message
48
**  digest type; there isn't a separate type for signing.
49
*/
50
51 1042a70f Eric Allman
EP_STAT
52
ep_crypto_sign_new(EP_CRYPTO_KEY *skey, int md_alg_id, EP_CRYPTO_MD **pmd)
53 f80ae9c0 Eric Allman
{
54 1042a70f Eric Allman
        EP_STAT estat = EP_STAT_OK;
55
        EP_CRYPTO_MD *md = NULL;
56 f7307b63 Eric Allman
        const EVP_MD *md_alg;
57 f80ae9c0 Eric Allman
        int istat;
58
59 f7307b63 Eric Allman
        md_alg = _ep_crypto_md_getalg_byid(md_alg_id);
60 f80ae9c0 Eric Allman
        if (md_alg == NULL)
61 970aa77d Eric Allman
        {
62 1042a70f Eric Allman
                estat = _ep_crypto_error(EP_STAT_CRYPTO_HASHALG,
63 970aa77d Eric Allman
                                "ep_crypto_sign_new: "
64 7023c91a Eric Allman
                                "unknown digest algorithm %d",
65 f7307b63 Eric Allman
                                md_alg_id);
66 1042a70f Eric Allman
                goto fail0;
67 970aa77d Eric Allman
        }
68 2f1080ba Eric Allman
        md = EVP_MD_CTX_create();
69 f80ae9c0 Eric Allman
        if (md == NULL)
70 970aa77d Eric Allman
        {
71 1042a70f Eric Allman
                estat = _ep_crypto_error(EP_STAT_CRYPTO_DIGEST,
72 970aa77d Eric Allman
                                "ep_crypto_sign_new: "
73 7023c91a Eric Allman
                                "cannot create message digest for signing");
74 1042a70f Eric Allman
                goto fail0;
75 970aa77d Eric Allman
        }
76 f80ae9c0 Eric Allman
        istat = EVP_DigestSignInit(md, NULL, md_alg, NULL, skey);
77
        if (istat != 1)
78
        {
79
                ep_crypto_md_free(md);
80 1042a70f Eric Allman
                estat = _ep_crypto_error(EP_STAT_CRYPTO_SIGN,
81 970aa77d Eric Allman
                                "ep_crypto_sign_new: "
82 7023c91a Eric Allman
                                "cannot initialize digest for signing");
83 1042a70f Eric Allman
                goto fail0;
84
        }
85
fail0:
86
        if (ep_dbg_test(Dbg, 64))
87
        {
88
                char ebuf[100];
89
                ep_dbg_printf("ep_crypto_sign_new(%d) => %p (%s)\n",        //DEBUG
90
                        md_alg_id, md,                                        //DEBUG
91
                        ep_stat_tostr(estat, ebuf, sizeof ebuf));
92 f80ae9c0 Eric Allman
        }
93 1042a70f Eric Allman
        *pmd = md;
94
        return estat;
95 f80ae9c0 Eric Allman
}
96
97
98 03834a8b Eric Allman
/*
99
**  Update a signing context.  This adds data to be signed.
100
*/
101 f80ae9c0 Eric Allman
102
EP_STAT
103
ep_crypto_sign_update(EP_CRYPTO_MD *md, void *dbuf, size_t dbufsize)
104
{
105
        int istat;
106
107 74920de3 Eric Allman
        ep_dbg_cprintf(Dbg, 64, "ep_crypto_sign_update(%p, %zd)\n",        //DEBUG
108
                        md, dbufsize);                                        //DEBUG
109 f80ae9c0 Eric Allman
        istat = EVP_DigestSignUpdate(md, dbuf, dbufsize);
110
        if (istat != 1)
111
        {
112 970aa77d Eric Allman
                (void) _ep_crypto_error(EP_STAT_CRYPTO_SIGN,
113
                                "ep_crypto_sign_update: "
114 7023c91a Eric Allman
                                "cannot update signing digest");
115 f80ae9c0 Eric Allman
        }
116
        return EP_STAT_OK;
117
}
118
119
120 03834a8b Eric Allman
/*
121
**  Finalize a signing context.
122
**
123
**        This returns the signature in sbuf and sbufsize, with
124
**        *sbufsize set to the size of sbuf on call, and modified
125
**        to be the number of bytes actually used.
126
**
127
**        The context cannot be used again.
128
*/
129
130 f80ae9c0 Eric Allman
EP_STAT
131 fc0cbc23 Eric Allman
ep_crypto_sign_final(EP_CRYPTO_MD *md, void *_sbuf, size_t *sbufsize)
132 f80ae9c0 Eric Allman
{
133
        int istat;
134 fc0cbc23 Eric Allman
        uint8_t *sbuf = (uint8_t *) _sbuf;
135 f80ae9c0 Eric Allman
136 74920de3 Eric Allman
        ep_dbg_cprintf(Dbg, 64, "ep_crypto_sign_final(%p, %zd)\n",        //DEBUG
137
                        md, *sbufsize);                                        //DEBUG
138 f80ae9c0 Eric Allman
        istat = EVP_DigestSignFinal(md, sbuf, sbufsize);
139
        if (istat != 1)
140
        {
141 970aa77d Eric Allman
                return _ep_crypto_error(EP_STAT_CRYPTO_SIGN,
142
                                "ep_crypto_sign_final: "
143 7023c91a Eric Allman
                                "cannot finalize signing digest");
144 f80ae9c0 Eric Allman
        }
145
        return EP_STAT_OK;
146
}
147
148
149 03834a8b Eric Allman
/*
150
**  Free the signing context.
151
*/
152
153 f80ae9c0 Eric Allman
void
154
ep_crypto_sign_free(EP_CRYPTO_MD *md)
155
{
156 2f1080ba Eric Allman
        EVP_MD_CTX_destroy(md);
157 f80ae9c0 Eric Allman
}