1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3 #include "tomcrypt_private.h"
4 
5 /**
6   @file ed25519_verify.c
7   Verify an Ed25519 signature, Steffen Jaeckel
8 */
9 
10 #ifdef LTC_CURVE25519
11 
s_ed25519_verify(const unsigned char * msg,unsigned long msglen,const unsigned char * sig,unsigned long siglen,const unsigned char * ctx,unsigned long ctxlen,int * stat,const curve25519_key * public_key)12 static int s_ed25519_verify(const  unsigned char *msg, unsigned long msglen,
13                             const  unsigned char *sig, unsigned long siglen,
14                             const  unsigned char *ctx, unsigned long ctxlen,
15                                              int *stat,
16                             const curve25519_key *public_key)
17 {
18    unsigned char* m;
19    unsigned long long mlen;
20    int err;
21 
22    LTC_ARGCHK(msg        != NULL);
23    LTC_ARGCHK(sig        != NULL);
24    LTC_ARGCHK(stat       != NULL);
25    LTC_ARGCHK(public_key != NULL);
26 
27    *stat = 0;
28 
29    if (siglen != 64uL) return CRYPT_INVALID_ARG;
30    if (public_key->algo != LTC_OID_ED25519) return CRYPT_PK_INVALID_TYPE;
31 
32    mlen = msglen + siglen;
33    if ((mlen < msglen) || (mlen < siglen)) return CRYPT_OVERFLOW;
34 
35    m = XMALLOC(mlen);
36    if (m == NULL) return CRYPT_MEM;
37 
38    XMEMCPY(m, sig, siglen);
39    XMEMCPY(m + siglen, msg, msglen);
40 
41    err = tweetnacl_crypto_sign_open(stat,
42                                     m, &mlen,
43                                     m, mlen,
44                                     ctx, ctxlen,
45                                     public_key->pub);
46 
47 #ifdef LTC_CLEAN_STACK
48    zeromem(m, msglen + siglen);
49 #endif
50    XFREE(m);
51 
52    return err;
53 }
54 
55 /**
56    Verify an Ed25519ctx signature.
57    @param msg             [in] The data to be verified
58    @param msglen          [in] The size of the data to be verified
59    @param sig             [in] The signature to be verified
60    @param siglen          [in] The size of the signature to be verified
61    @param ctx             [in] The context
62    @param ctxlen          [in] The size of the context
63    @param stat            [out] The result of the signature verification, 1==valid, 0==invalid
64    @param public_key      [in] The public Ed25519 key in the pair
65    @return CRYPT_OK if successful
66 */
ed25519ctx_verify(const unsigned char * msg,unsigned long msglen,const unsigned char * sig,unsigned long siglen,const unsigned char * ctx,unsigned long ctxlen,int * stat,const curve25519_key * public_key)67 int ed25519ctx_verify(const  unsigned char *msg, unsigned long msglen,
68                       const  unsigned char *sig, unsigned long siglen,
69                       const  unsigned char *ctx, unsigned long ctxlen,
70                                        int *stat,
71                       const curve25519_key *public_key)
72 {
73    unsigned char ctx_prefix[292];
74    unsigned long ctx_prefix_size = sizeof(ctx_prefix);
75 
76    LTC_ARGCHK(ctx != NULL);
77 
78    if (ec25519_crypto_ctx(ctx_prefix, &ctx_prefix_size, 0, ctx, ctxlen) != CRYPT_OK)
79       return CRYPT_INVALID_ARG;
80 
81    return s_ed25519_verify(msg, msglen, sig, siglen, ctx_prefix, ctx_prefix_size, stat, public_key);
82 }
83 
84 /**
85    Verify an Ed25519ph signature.
86    @param msg             [in] The data to be verified
87    @param msglen          [in] The size of the data to be verified
88    @param sig             [in] The signature to be verified
89    @param siglen          [in] The size of the signature to be verified
90    @param ctx             [in] The context
91    @param ctxlen          [in] The size of the context
92    @param stat            [out] The result of the signature verification, 1==valid, 0==invalid
93    @param public_key      [in] The public Ed25519 key in the pair
94    @return CRYPT_OK if successful
95 */
ed25519ph_verify(const unsigned char * msg,unsigned long msglen,const unsigned char * sig,unsigned long siglen,const unsigned char * ctx,unsigned long ctxlen,int * stat,const curve25519_key * public_key)96 int ed25519ph_verify(const  unsigned char *msg, unsigned long msglen,
97                      const  unsigned char *sig, unsigned long siglen,
98                      const  unsigned char *ctx, unsigned long ctxlen,
99                                       int *stat,
100                      const curve25519_key *public_key)
101 {
102    int err;
103    unsigned char msg_hash[64];
104    unsigned char ctx_prefix[292];
105    unsigned long ctx_prefix_size = sizeof(ctx_prefix);
106 
107    if ((err = ec25519_crypto_ctx(ctx_prefix, &ctx_prefix_size, 1, ctx, ctxlen)) != CRYPT_OK)
108       return err;
109 
110    if ((err = tweetnacl_crypto_ph(msg_hash, msg, msglen)) != CRYPT_OK)
111       return err;
112 
113    return s_ed25519_verify(msg_hash, sizeof(msg_hash), sig, siglen, ctx_prefix, ctx_prefix_size, stat, public_key);
114 }
115 
116 /**
117    Verify an Ed25519 signature.
118    @param msg             [in] The data to be verified
119    @param msglen          [in] The size of the data to be verified
120    @param sig             [in] The signature to be verified
121    @param siglen          [in] The size of the signature to be verified
122    @param stat            [out] The result of the signature verification, 1==valid, 0==invalid
123    @param public_key      [in] The public Ed25519 key in the pair
124    @return CRYPT_OK if successful
125 */
ed25519_verify(const unsigned char * msg,unsigned long msglen,const unsigned char * sig,unsigned long siglen,int * stat,const curve25519_key * public_key)126 int ed25519_verify(const  unsigned char *msg, unsigned long msglen,
127                    const  unsigned char *sig, unsigned long siglen,
128                                     int *stat,
129                    const curve25519_key *public_key)
130 {
131    return s_ed25519_verify(msg, msglen, sig, siglen, NULL, 0, stat, public_key);
132 }
133 
134 #endif
135