1d4afb5ceSopenharmony_ci/* $OpenBSD: ed25519.c,v 1.3 2013/12/09 11:03:45 markus Exp $ */ 2d4afb5ceSopenharmony_ci 3d4afb5ceSopenharmony_ci/* 4d4afb5ceSopenharmony_ci * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange, 5d4afb5ceSopenharmony_ci * Peter Schwabe, Bo-Yin Yang. 6d4afb5ceSopenharmony_ci * Copied from supercop-20130419/crypto_sign/ed25519/ref/ed25519.c 7d4afb5ceSopenharmony_ci * 8d4afb5ceSopenharmony_ci * Modified to use lws genhash by Andy Green <andy@warmcat.com> 9d4afb5ceSopenharmony_ci */ 10d4afb5ceSopenharmony_ci 11d4afb5ceSopenharmony_ci#include <libwebsockets.h> 12d4afb5ceSopenharmony_ci#include <lws-ssh.h> 13d4afb5ceSopenharmony_ci#include "ge25519.h" 14d4afb5ceSopenharmony_ci 15d4afb5ceSopenharmony_ciint 16d4afb5ceSopenharmony_cicrypto_hash_sha512(uint8_t *hash64, const uint8_t *data, size_t len) 17d4afb5ceSopenharmony_ci{ 18d4afb5ceSopenharmony_ci struct lws_genhash_ctx ctx; 19d4afb5ceSopenharmony_ci int ret; 20d4afb5ceSopenharmony_ci 21d4afb5ceSopenharmony_ci if (lws_genhash_init(&ctx, LWS_GENHASH_TYPE_SHA512)) { 22d4afb5ceSopenharmony_ci lwsl_notice("Failed to init SHA512\n"); 23d4afb5ceSopenharmony_ci return 0; 24d4afb5ceSopenharmony_ci } 25d4afb5ceSopenharmony_ci 26d4afb5ceSopenharmony_ci ret = lws_genhash_update(&ctx, data, len); 27d4afb5ceSopenharmony_ci 28d4afb5ceSopenharmony_ci if (lws_genhash_destroy(&ctx, hash64)) 29d4afb5ceSopenharmony_ci lwsl_notice("genhash destroy failed\n"); 30d4afb5ceSopenharmony_ci 31d4afb5ceSopenharmony_ci return ret ? 0 : 64; 32d4afb5ceSopenharmony_ci} 33d4afb5ceSopenharmony_ci 34d4afb5ceSopenharmony_ci 35d4afb5ceSopenharmony_cistatic void 36d4afb5ceSopenharmony_ciget_hram(unsigned char *hram, const unsigned char *sm, 37d4afb5ceSopenharmony_ci const unsigned char *pk, unsigned char *playground, 38d4afb5ceSopenharmony_ci size_t smlen) 39d4afb5ceSopenharmony_ci{ 40d4afb5ceSopenharmony_ci unsigned long long i; 41d4afb5ceSopenharmony_ci 42d4afb5ceSopenharmony_ci for (i = 0; i < 32; ++i) 43d4afb5ceSopenharmony_ci playground[i] = sm[i]; 44d4afb5ceSopenharmony_ci for (i = 32; i < 64; ++i) 45d4afb5ceSopenharmony_ci playground[i] = pk[i-32]; 46d4afb5ceSopenharmony_ci for (i = 64; i < smlen; ++i) 47d4afb5ceSopenharmony_ci playground[i] = sm[i]; 48d4afb5ceSopenharmony_ci 49d4afb5ceSopenharmony_ci crypto_hash_sha512(hram, playground, smlen); 50d4afb5ceSopenharmony_ci} 51d4afb5ceSopenharmony_ci 52d4afb5ceSopenharmony_ci 53d4afb5ceSopenharmony_ciint crypto_sign_ed25519_keypair( 54d4afb5ceSopenharmony_ci struct lws_context *context, 55d4afb5ceSopenharmony_ci unsigned char *pk, 56d4afb5ceSopenharmony_ci unsigned char *sk 57d4afb5ceSopenharmony_ci ) 58d4afb5ceSopenharmony_ci{ 59d4afb5ceSopenharmony_ci sc25519 scsk; 60d4afb5ceSopenharmony_ci ge25519 gepk; 61d4afb5ceSopenharmony_ci unsigned char extsk[64]; 62d4afb5ceSopenharmony_ci int i; 63d4afb5ceSopenharmony_ci 64d4afb5ceSopenharmony_ci lws_get_random(context, sk, 32); 65d4afb5ceSopenharmony_ci crypto_hash_sha512(extsk, sk, 32); 66d4afb5ceSopenharmony_ci extsk[0] &= 248; 67d4afb5ceSopenharmony_ci extsk[31] &= 127; 68d4afb5ceSopenharmony_ci extsk[31] |= 64; 69d4afb5ceSopenharmony_ci 70d4afb5ceSopenharmony_ci sc25519_from32bytes(&scsk,extsk); 71d4afb5ceSopenharmony_ci 72d4afb5ceSopenharmony_ci ge25519_scalarmult_base(&gepk, &scsk); 73d4afb5ceSopenharmony_ci ge25519_pack(pk, &gepk); 74d4afb5ceSopenharmony_ci for(i=0;i<32;i++) 75d4afb5ceSopenharmony_ci sk[32 + i] = pk[i]; 76d4afb5ceSopenharmony_ci return 0; 77d4afb5ceSopenharmony_ci} 78d4afb5ceSopenharmony_ci 79d4afb5ceSopenharmony_ciint crypto_sign_ed25519( 80d4afb5ceSopenharmony_ci unsigned char *sm, 81d4afb5ceSopenharmony_ci unsigned long long *smlen, 82d4afb5ceSopenharmony_ci const unsigned char *m, size_t mlen, 83d4afb5ceSopenharmony_ci const unsigned char *sk 84d4afb5ceSopenharmony_ci ) 85d4afb5ceSopenharmony_ci{ 86d4afb5ceSopenharmony_ci sc25519 sck, scs, scsk; 87d4afb5ceSopenharmony_ci ge25519 ger; 88d4afb5ceSopenharmony_ci unsigned char r[32]; 89d4afb5ceSopenharmony_ci unsigned char s[32]; 90d4afb5ceSopenharmony_ci unsigned char extsk[64]; 91d4afb5ceSopenharmony_ci unsigned long long i; 92d4afb5ceSopenharmony_ci unsigned char hmg[crypto_hash_sha512_BYTES]; 93d4afb5ceSopenharmony_ci unsigned char hram[crypto_hash_sha512_BYTES]; 94d4afb5ceSopenharmony_ci 95d4afb5ceSopenharmony_ci crypto_hash_sha512(extsk, sk, 32); 96d4afb5ceSopenharmony_ci extsk[0] &= 248; 97d4afb5ceSopenharmony_ci extsk[31] &= 127; 98d4afb5ceSopenharmony_ci extsk[31] |= 64; 99d4afb5ceSopenharmony_ci 100d4afb5ceSopenharmony_ci *smlen = mlen+64; 101d4afb5ceSopenharmony_ci for(i=0;i<mlen;i++) 102d4afb5ceSopenharmony_ci sm[64 + i] = m[i]; 103d4afb5ceSopenharmony_ci for(i=0;i<32;i++) 104d4afb5ceSopenharmony_ci sm[32 + i] = extsk[32+i]; 105d4afb5ceSopenharmony_ci 106d4afb5ceSopenharmony_ci crypto_hash_sha512(hmg, sm+32, mlen+32); 107d4afb5ceSopenharmony_ci /* Generate k as h(extsk[32],...,extsk[63],m) */ 108d4afb5ceSopenharmony_ci 109d4afb5ceSopenharmony_ci /* Computation of R */ 110d4afb5ceSopenharmony_ci sc25519_from64bytes(&sck, hmg); 111d4afb5ceSopenharmony_ci ge25519_scalarmult_base(&ger, &sck); 112d4afb5ceSopenharmony_ci ge25519_pack(r, &ger); 113d4afb5ceSopenharmony_ci 114d4afb5ceSopenharmony_ci /* Computation of s */ 115d4afb5ceSopenharmony_ci for (i = 0; i < 32; i++) 116d4afb5ceSopenharmony_ci sm[i] = r[i]; 117d4afb5ceSopenharmony_ci 118d4afb5ceSopenharmony_ci get_hram(hram, sm, sk + 32, sm, (size_t)mlen + 64); 119d4afb5ceSopenharmony_ci 120d4afb5ceSopenharmony_ci sc25519_from64bytes(&scs, hram); 121d4afb5ceSopenharmony_ci sc25519_from32bytes(&scsk, extsk); 122d4afb5ceSopenharmony_ci sc25519_mul(&scs, &scs, &scsk); 123d4afb5ceSopenharmony_ci 124d4afb5ceSopenharmony_ci sc25519_add(&scs, &scs, &sck); 125d4afb5ceSopenharmony_ci 126d4afb5ceSopenharmony_ci sc25519_to32bytes(s,&scs); /* cat s */ 127d4afb5ceSopenharmony_ci for (i = 0; i < 32; i++) 128d4afb5ceSopenharmony_ci sm[32 + i] = s[i]; 129d4afb5ceSopenharmony_ci 130d4afb5ceSopenharmony_ci return 0; 131d4afb5ceSopenharmony_ci} 132d4afb5ceSopenharmony_ci 133d4afb5ceSopenharmony_ciint crypto_verify_32(const unsigned char *x,const unsigned char *y) 134d4afb5ceSopenharmony_ci{ 135d4afb5ceSopenharmony_ci unsigned int differentbits = 0; 136d4afb5ceSopenharmony_ci#define F(i) differentbits |= x[i] ^ y[i]; 137d4afb5ceSopenharmony_ci F(0) 138d4afb5ceSopenharmony_ci F(1) 139d4afb5ceSopenharmony_ci F(2) 140d4afb5ceSopenharmony_ci F(3) 141d4afb5ceSopenharmony_ci F(4) 142d4afb5ceSopenharmony_ci F(5) 143d4afb5ceSopenharmony_ci F(6) 144d4afb5ceSopenharmony_ci F(7) 145d4afb5ceSopenharmony_ci F(8) 146d4afb5ceSopenharmony_ci F(9) 147d4afb5ceSopenharmony_ci F(10) 148d4afb5ceSopenharmony_ci F(11) 149d4afb5ceSopenharmony_ci F(12) 150d4afb5ceSopenharmony_ci F(13) 151d4afb5ceSopenharmony_ci F(14) 152d4afb5ceSopenharmony_ci F(15) 153d4afb5ceSopenharmony_ci F(16) 154d4afb5ceSopenharmony_ci F(17) 155d4afb5ceSopenharmony_ci F(18) 156d4afb5ceSopenharmony_ci F(19) 157d4afb5ceSopenharmony_ci F(20) 158d4afb5ceSopenharmony_ci F(21) 159d4afb5ceSopenharmony_ci F(22) 160d4afb5ceSopenharmony_ci F(23) 161d4afb5ceSopenharmony_ci F(24) 162d4afb5ceSopenharmony_ci F(25) 163d4afb5ceSopenharmony_ci F(26) 164d4afb5ceSopenharmony_ci F(27) 165d4afb5ceSopenharmony_ci F(28) 166d4afb5ceSopenharmony_ci F(29) 167d4afb5ceSopenharmony_ci F(30) 168d4afb5ceSopenharmony_ci F(31) 169d4afb5ceSopenharmony_ci return (int)((1 & ((differentbits - 1) >> 8)) - 1); 170d4afb5ceSopenharmony_ci} 171d4afb5ceSopenharmony_ci 172d4afb5ceSopenharmony_ciint crypto_sign_ed25519_open( 173d4afb5ceSopenharmony_ci unsigned char *m,unsigned long long *mlen, 174d4afb5ceSopenharmony_ci const unsigned char *sm,unsigned long long smlen, 175d4afb5ceSopenharmony_ci const unsigned char *pk 176d4afb5ceSopenharmony_ci ) 177d4afb5ceSopenharmony_ci{ 178d4afb5ceSopenharmony_ci unsigned int i; 179d4afb5ceSopenharmony_ci int ret; 180d4afb5ceSopenharmony_ci unsigned char t2[32]; 181d4afb5ceSopenharmony_ci ge25519 get1, get2; 182d4afb5ceSopenharmony_ci sc25519 schram, scs; 183d4afb5ceSopenharmony_ci unsigned char hram[crypto_hash_sha512_BYTES]; 184d4afb5ceSopenharmony_ci 185d4afb5ceSopenharmony_ci *mlen = (unsigned long long) -1; 186d4afb5ceSopenharmony_ci if (smlen < 64) { 187d4afb5ceSopenharmony_ci lwsl_notice("a\n"); 188d4afb5ceSopenharmony_ci 189d4afb5ceSopenharmony_ci return -1; 190d4afb5ceSopenharmony_ci } 191d4afb5ceSopenharmony_ci 192d4afb5ceSopenharmony_ci if (ge25519_unpackneg_vartime(&get1, pk)) { 193d4afb5ceSopenharmony_ci lwsl_notice("b\n"); 194d4afb5ceSopenharmony_ci return -1; 195d4afb5ceSopenharmony_ci } 196d4afb5ceSopenharmony_ci 197d4afb5ceSopenharmony_ci get_hram(hram,sm,pk,m, (size_t)smlen); 198d4afb5ceSopenharmony_ci 199d4afb5ceSopenharmony_ci sc25519_from64bytes(&schram, hram); 200d4afb5ceSopenharmony_ci 201d4afb5ceSopenharmony_ci sc25519_from32bytes(&scs, sm+32); 202d4afb5ceSopenharmony_ci 203d4afb5ceSopenharmony_ci ge25519_double_scalarmult_vartime(&get2, &get1, &schram, &ge25519_base, &scs); 204d4afb5ceSopenharmony_ci ge25519_pack(t2, &get2); 205d4afb5ceSopenharmony_ci 206d4afb5ceSopenharmony_ci ret = crypto_verify_32(sm, t2); 207d4afb5ceSopenharmony_ci lwsl_notice("vf says %d\n", ret); 208d4afb5ceSopenharmony_ci 209d4afb5ceSopenharmony_ci if (!ret) 210d4afb5ceSopenharmony_ci { 211d4afb5ceSopenharmony_ci for(i=0;i<smlen-64;i++) 212d4afb5ceSopenharmony_ci m[i] = sm[i + 64]; 213d4afb5ceSopenharmony_ci *mlen = smlen-64; 214d4afb5ceSopenharmony_ci } 215d4afb5ceSopenharmony_ci else 216d4afb5ceSopenharmony_ci { 217d4afb5ceSopenharmony_ci for(i=0;i<smlen-64;i++) 218d4afb5ceSopenharmony_ci m[i] = 0; 219d4afb5ceSopenharmony_ci } 220d4afb5ceSopenharmony_ci return ret; 221d4afb5ceSopenharmony_ci} 222