Project

General

Profile

Statistics
| Branch: | Tag: | Revision:

gdp / ep / ep_crypto_sign.c @ master

History | View | Annotate | Download (4.18 KB)

1
/* vim: set ai sw=8 sts=8 ts=8 : */
2

    
3
/***********************************************************************
4
**  ----- BEGIN LICENSE BLOCK -----
5
**        LIBEP: Enhanced Portability Library (Reduced Edition)
6
**
7
**        Copyright (c) 2008-2019, Eric P. Allman.  All rights reserved.
8
**        Copyright (c) 2015-2019, Regents of the University of California.
9
**        All rights reserved.
10
**
11
**        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
**
17
**        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
**
22
**        REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
23
**        LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24
**        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
**  ----- END LICENSE BLOCK -----
29
***********************************************************************/
30

    
31
/*
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
#include <ep/ep.h>
40
#include <ep/ep_crypto.h>
41
#include <ep/ep_dbg.h>
42

    
43
static EP_DBG        Dbg = EP_DBG_INIT("libep.crypto.sign", "cryptographic signature generation");
44

    
45

    
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
EP_STAT
52
ep_crypto_sign_new(EP_CRYPTO_KEY *skey, int md_alg_id, EP_CRYPTO_MD **pmd)
53
{
54
        EP_STAT estat = EP_STAT_OK;
55
        EP_CRYPTO_MD *md = NULL;
56
        const EVP_MD *md_alg;
57
        int istat;
58

    
59
        md_alg = _ep_crypto_md_getalg_byid(md_alg_id);
60
        if (md_alg == NULL)
61
        {
62
                estat = _ep_crypto_error(EP_STAT_CRYPTO_HASHALG,
63
                                "ep_crypto_sign_new: "
64
                                "unknown digest algorithm %d",
65
                                md_alg_id);
66
                goto fail0;
67
        }
68
        md = EVP_MD_CTX_create();
69
        if (md == NULL)
70
        {
71
                estat = _ep_crypto_error(EP_STAT_CRYPTO_DIGEST,
72
                                "ep_crypto_sign_new: "
73
                                "cannot create message digest for signing");
74
                goto fail0;
75
        }
76
        istat = EVP_DigestSignInit(md, NULL, md_alg, NULL, skey);
77
        if (istat != 1)
78
        {
79
                ep_crypto_md_free(md);
80
                estat = _ep_crypto_error(EP_STAT_CRYPTO_SIGN,
81
                                "ep_crypto_sign_new: "
82
                                "cannot initialize digest for signing");
83
                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
        }
93
        *pmd = md;
94
        return estat;
95
}
96

    
97

    
98
/*
99
**  Update a signing context.  This adds data to be signed.
100
*/
101

    
102
EP_STAT
103
ep_crypto_sign_update(EP_CRYPTO_MD *md, void *dbuf, size_t dbufsize)
104
{
105
        int istat;
106

    
107
        ep_dbg_cprintf(Dbg, 64, "ep_crypto_sign_update(%p, %zd)\n",        //DEBUG
108
                        md, dbufsize);                                        //DEBUG
109
        istat = EVP_DigestSignUpdate(md, dbuf, dbufsize);
110
        if (istat != 1)
111
        {
112
                (void) _ep_crypto_error(EP_STAT_CRYPTO_SIGN,
113
                                "ep_crypto_sign_update: "
114
                                "cannot update signing digest");
115
        }
116
        return EP_STAT_OK;
117
}
118

    
119

    
120
/*
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
EP_STAT
131
ep_crypto_sign_final(EP_CRYPTO_MD *md, void *_sbuf, size_t *sbufsize)
132
{
133
        int istat;
134
        uint8_t *sbuf = (uint8_t *) _sbuf;
135

    
136
        ep_dbg_cprintf(Dbg, 64, "ep_crypto_sign_final(%p, %zd)\n",        //DEBUG
137
                        md, *sbufsize);                                        //DEBUG
138
        istat = EVP_DigestSignFinal(md, sbuf, sbufsize);
139
        if (istat != 1)
140
        {
141
                return _ep_crypto_error(EP_STAT_CRYPTO_SIGN,
142
                                "ep_crypto_sign_final: "
143
                                "cannot finalize signing digest");
144
        }
145
        return EP_STAT_OK;
146
}
147

    
148

    
149
/*
150
**  Free the signing context.
151
*/
152

    
153
void
154
ep_crypto_sign_free(EP_CRYPTO_MD *md)
155
{
156
        EVP_MD_CTX_destroy(md);
157
}