Codebase list libcryptx-perl / 9fcf307
Add initial PK::ED25519 and PK:X25519 manuel 4 years ago
4 changed file(s) with 421 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
146146 int pindex;
147147 ecc_key key;
148148 } *Crypt__PK__ECC;
149
150 struct curve25519_struct {
151 prng_state pstate;
152 int pindex;
153 curve25519_key key;
154 } ;
155 typedef struct curve25519_struct *Crypt__PK__ED25519; /* used by Crypt::PK::ED25519 */
156 typedef struct curve25519_struct *Crypt__PK__X25519; /* used by Crypt::PK::X25519 */
149157
150158 int mp_tohex_with_leading_zero(mp_int * a, char *str, int maxlen, int minlen) {
151159 int len, rv;
746754 INCLUDE: inc/CryptX_PK_DSA.xs.inc
747755 INCLUDE: inc/CryptX_PK_DH.xs.inc
748756 INCLUDE: inc/CryptX_PK_ECC.xs.inc
757 INCLUDE: inc/CryptX_PK_ED25519.xs.inc
758 INCLUDE: inc/CryptX_PK_X25519.xs.inc
749759
750760 INCLUDE: inc/CryptX_KeyDerivation.xs.inc
751761
0 MODULE = CryptX PACKAGE = Crypt::PK::ED25519
1
2 PROTOTYPES: DISABLE
3
4 Crypt::PK::ED25519
5 _new(Class)
6 CODE:
7 {
8 int rv;
9 Newz(0, RETVAL, 1, struct curve25519_struct);
10 if (!RETVAL) croak("FATAL: Newz failed");
11 RETVAL->pindex = find_prng("chacha20");
12 RETVAL->key.type = -1;
13 if (RETVAL->pindex == -1) {
14 Safefree(RETVAL);
15 croak("FATAL: find_prng('chacha20') failed");
16 }
17 rv = rng_make_prng(320, RETVAL->pindex, &RETVAL->pstate, NULL); /* 320bits = 40bytes */
18 if (rv != CRYPT_OK) {
19 Safefree(RETVAL);
20 croak("FATAL: rng_make_prng failed: %s", error_to_string(rv));
21 }
22 }
23 OUTPUT:
24 RETVAL
25
26 void
27 generate_key(Crypt::PK::ED25519 self)
28 PPCODE:
29 {
30 int rv;
31 /* gen the key */
32 rv = ed25519_make_key(&self->pstate, self->pindex, &self->key);
33 if (rv != CRYPT_OK) croak("FATAL: ed25519_make_key failed: %s", error_to_string(rv));
34 XPUSHs(ST(0)); /* return self */
35 }
36
37 void
38 _import(Crypt::PK::ED25519 self, SV * key_data)
39 PPCODE:
40 {
41 int rv;
42 unsigned char *data=NULL;
43 STRLEN data_len=0;
44
45 data = (unsigned char *)SvPVbyte(key_data, data_len);
46 self->key.type = -1;
47 rv = ed25519_import(data, (unsigned long)data_len, &self->key);
48 if (rv != CRYPT_OK) croak("FATAL: ed25519_import failed: %s", error_to_string(rv));
49 XPUSHs(ST(0)); /* return self */
50 }
51
52 void
53 _import_pkcs8(Crypt::PK::ED25519 self, SV * key_data, SV * passwd)
54 PPCODE:
55 {
56 int rv;
57 unsigned char *data=NULL, *pwd=NULL;
58 STRLEN data_len=0, pwd_len=0;
59
60 data = (unsigned char *)SvPVbyte(key_data, data_len);
61 if (SvOK(passwd)) {
62 pwd = (unsigned char *)SvPVbyte(passwd, pwd_len);
63 }
64 self->key.type = -1;
65 rv = ed25519_import_pkcs8(data, (unsigned long)data_len, pwd, (unsigned long)pwd_len, &self->key);
66 if (rv != CRYPT_OK) croak("FATAL: ed25519_import_pkcs8 failed: %s", error_to_string(rv));
67 XPUSHs(ST(0)); /* return self */
68 }
69
70 void
71 _import_x509(Crypt::PK::ED25519 self, SV * key_data)
72 PPCODE:
73 {
74 int rv;
75 unsigned char *data=NULL;
76 STRLEN data_len=0;
77
78 data = (unsigned char *)SvPVbyte(key_data, data_len);
79 self->key.type = -1;
80 rv = ed25519_import_x509(data, (unsigned long)data_len, &self->key);
81 if (rv != CRYPT_OK) croak("FATAL: ed25519_import_x509 failed: %s", error_to_string(rv));
82 XPUSHs(ST(0)); /* return self */
83 }
84
85 void
86 _import_key_data(Crypt::PK::ED25519 self, SV * priv, SV * pub)
87 PPCODE:
88 {
89 int rv, type;
90 unsigned char *priv_data=NULL, *pub_data=NULL;
91 STRLEN priv_len=0, pub_len=0;
92
93 if (SvOK(priv)) {
94 priv_data = (unsigned char *)SvPVbyte(priv, priv_len);
95 }
96 if (SvOK(pub)) {
97 pub_data = (unsigned char *)SvPVbyte(pub, pub_len);
98 }
99 self->key.type = -1;
100 rv = ed25519_set_key(priv_data, (unsigned long)priv_len, pub_data, (unsigned long)pub_len, &self->key);
101 if (rv != CRYPT_OK) croak("FATAL: ed25519_set_key failed: %s", error_to_string(rv));
102 XPUSHs(ST(0)); /* return self */
103 }
104
105 int
106 is_private(Crypt::PK::ED25519 self)
107 CODE:
108 if (self->key.type == -1) XSRETURN_UNDEF;
109 RETVAL = (self->key.type == PK_PRIVATE) ? 1 : 0;
110 OUTPUT:
111 RETVAL
112
113 SV*
114 key2hash(Crypt::PK::ED25519 self)
115 PREINIT:
116 HV *rv_hash;
117 char buf[20001];
118 SV **not_used;
119 CODE:
120 if (self->key.type == -1) XSRETURN_UNDEF;
121 rv_hash = newHV();
122 /* priv */
123 if (self->key.type == PK_PRIVATE) {
124 not_used = hv_store(rv_hash, "priv", 4, newSVpv(self->key.priv, sizeof(self->key.priv)), 0);
125 }
126 else {
127 not_used = hv_store(rv_hash, "priv", 4, &PL_sv_undef, 0);
128 }
129 /* pub */
130 not_used = hv_store(rv_hash, "pub", 3, newSVpv(self->key.pub, sizeof(self->key.pub)), 0);
131 /* algo */
132 not_used = hv_store(rv_hash, "algo", 4, newSVpv("ed25519", 0), 0);
133 LTC_UNUSED_PARAM(not_used);
134 RETVAL = newRV_noinc((SV*)rv_hash);
135 OUTPUT:
136 RETVAL
137
138 SV*
139 export_key_der(Crypt::PK::ED25519 self, char * type)
140 CODE:
141 {
142 int rv;
143 unsigned char out[4096];
144 unsigned long int out_len = sizeof(out);
145
146 RETVAL = newSVpvn(NULL, 0); /* undef */
147 if (strnEQ(type, "private", 7)) {
148 rv = ed25519_export(out, &out_len, PK_PRIVATE, &self->key);
149 if (rv != CRYPT_OK) croak("FATAL: ed25519_export(PK_PRIVATE) failed: %s", error_to_string(rv));
150 RETVAL = newSVpvn((char*)out, out_len);
151 }
152 else if (strnEQ(type, "public", 6)) {
153 rv = ed25519_export(out, &out_len, PK_PUBLIC|PK_STD, &self->key);
154 if (rv != CRYPT_OK) croak("FATAL: ed25519_export(PK_PUBLIC|PK_STD) failed: %s", error_to_string(rv));
155 RETVAL = newSVpvn((char*)out, out_len);
156 }
157 else {
158 croak("FATAL: export_key_der invalid type '%s'", type);
159 }
160 }
161 OUTPUT:
162 RETVAL
163
164 SV *
165 sign_hash(Crypt::PK::ED25519 self, SV * data, const char * hash_name = "SHA1")
166 ALIAS:
167 sign_message = 1
168 CODE:
169 {
170 int rv, id;
171 unsigned char buffer[1024], tmp[MAXBLOCKSIZE], *data_ptr = NULL;
172 unsigned long tmp_len = MAXBLOCKSIZE, buffer_len = 1024;
173 STRLEN data_len = 0;
174
175 data_ptr = (unsigned char *)SvPVbyte(data, data_len);
176 if (ix == 1) {
177 id = _find_hash(hash_name);
178 if (id == -1) croak("FATAL: find_hash failed for '%s'", hash_name);
179 rv = hash_memory(id, data_ptr, (unsigned long)data_len, tmp, &tmp_len);
180 if (rv != CRYPT_OK) croak("FATAL: hash_memory failed: %s", error_to_string(rv));
181 data_ptr = tmp;
182 data_len = tmp_len;
183 }
184 rv = ed25519_sign(data_ptr, (unsigned long)data_len, buffer, &buffer_len, &self->key);
185 if (rv != CRYPT_OK) croak("FATAL: ed25519_sign failed: %s", error_to_string(rv));
186 RETVAL = newSVpvn((char*)buffer, buffer_len);
187 }
188 OUTPUT:
189 RETVAL
190
191 int
192 verify_hash(Crypt::PK::ED25519 self, SV * sig, SV * data, const char * hash_name = "SHA1")
193 ALIAS:
194 verify_message = 1
195 CODE:
196 {
197 int rv, stat, id;
198 unsigned char tmp[MAXBLOCKSIZE], *data_ptr = NULL, *sig_ptr = NULL;
199 unsigned long tmp_len = MAXBLOCKSIZE;
200 STRLEN data_len = 0, sig_len = 0;
201
202 data_ptr = (unsigned char *)SvPVbyte(data, data_len);
203 sig_ptr = (unsigned char *)SvPVbyte(sig, sig_len);
204 if (ix == 1) {
205 id = _find_hash(hash_name);
206 if (id == -1) croak("FATAL: find_hash failed for '%s'", hash_name);
207 rv = hash_memory(id, data_ptr, (unsigned long)data_len, tmp, &tmp_len);
208 if (rv != CRYPT_OK) croak("FATAL: hash_memory failed: %s", error_to_string(rv));
209 data_ptr = tmp;
210 data_len = tmp_len;
211 }
212 RETVAL = 1;
213 stat = 0;
214 rv = ed25519_verify(data_ptr, (unsigned long)data_len, sig_ptr, (unsigned long)sig_len, &stat, &self->key);
215 if (rv != CRYPT_OK || stat != 1) RETVAL = 0;
216 }
217 OUTPUT:
218 RETVAL
219
220 void
221 DESTROY(Crypt::PK::ED25519 self)
222 CODE:
223 Safefree(self);
224
0 MODULE = CryptX PACKAGE = Crypt::PK::X25519
1
2 PROTOTYPES: DISABLE
3
4 Crypt::PK::X25519
5 _new(Class)
6 CODE:
7 {
8 int rv;
9 Newz(0, RETVAL, 1, struct curve25519_struct);
10 if (!RETVAL) croak("FATAL: Newz failed");
11 RETVAL->pindex = find_prng("chacha20");
12 RETVAL->key.type = -1;
13 if (RETVAL->pindex == -1) {
14 Safefree(RETVAL);
15 croak("FATAL: find_prng('chacha20') failed");
16 }
17 rv = rng_make_prng(320, RETVAL->pindex, &RETVAL->pstate, NULL); /* 320bits = 40bytes */
18 if (rv != CRYPT_OK) {
19 Safefree(RETVAL);
20 croak("FATAL: rng_make_prng failed: %s", error_to_string(rv));
21 }
22 }
23 OUTPUT:
24 RETVAL
25
26 void
27 generate_key(Crypt::PK::X25519 self)
28 PPCODE:
29 {
30 int rv;
31 /* gen the key */
32 rv = x25519_make_key(&self->pstate, self->pindex, &self->key);
33 if (rv != CRYPT_OK) croak("FATAL: x25519_make_key failed: %s", error_to_string(rv));
34 XPUSHs(ST(0)); /* return self */
35 }
36
37 void
38 _import(Crypt::PK::X25519 self, SV * key_data)
39 PPCODE:
40 {
41 int rv;
42 unsigned char *data=NULL;
43 STRLEN data_len=0;
44
45 data = (unsigned char *)SvPVbyte(key_data, data_len);
46 self->key.type = -1;
47 rv = x25519_import(data, (unsigned long)data_len, &self->key);
48 if (rv != CRYPT_OK) croak("FATAL: x25519_import failed: %s", error_to_string(rv));
49 XPUSHs(ST(0)); /* return self */
50 }
51
52 void
53 _import_pkcs8(Crypt::PK::X25519 self, SV * key_data, SV * passwd)
54 PPCODE:
55 {
56 int rv;
57 unsigned char *data=NULL, *pwd=NULL;
58 STRLEN data_len=0, pwd_len=0;
59
60 data = (unsigned char *)SvPVbyte(key_data, data_len);
61 if (SvOK(passwd)) {
62 pwd = (unsigned char *)SvPVbyte(passwd, pwd_len);
63 }
64 self->key.type = -1;
65 rv = x25519_import_pkcs8(data, (unsigned long)data_len, pwd, (unsigned long)pwd_len, &self->key);
66 if (rv != CRYPT_OK) croak("FATAL: x25519_import_pkcs8 failed: %s", error_to_string(rv));
67 XPUSHs(ST(0)); /* return self */
68 }
69
70 void
71 _import_x509(Crypt::PK::X25519 self, SV * key_data)
72 PPCODE:
73 {
74 int rv;
75 unsigned char *data=NULL;
76 STRLEN data_len=0;
77
78 data = (unsigned char *)SvPVbyte(key_data, data_len);
79 self->key.type = -1;
80 rv = x25519_import_x509(data, (unsigned long)data_len, &self->key);
81 if (rv != CRYPT_OK) croak("FATAL: x25519_import_x509 failed: %s", error_to_string(rv));
82 XPUSHs(ST(0)); /* return self */
83 }
84
85 void
86 _import_key_data(Crypt::PK::X25519 self, SV * priv, SV * pub)
87 PPCODE:
88 {
89 int rv, type;
90 unsigned char *priv_data=NULL, *pub_data=NULL;
91 STRLEN priv_len=0, pub_len=0;
92
93 if (SvOK(priv)) {
94 priv_data = (unsigned char *)SvPVbyte(priv, priv_len);
95 }
96 if (SvOK(pub)) {
97 pub_data = (unsigned char *)SvPVbyte(pub, pub_len);
98 }
99 self->key.type = -1;
100 rv = x25519_set_key(priv_data, (unsigned long)priv_len, pub_data, (unsigned long)pub_len, &self->key);
101 if (rv != CRYPT_OK) croak("FATAL: x25519_set_key failed: %s", error_to_string(rv));
102 XPUSHs(ST(0)); /* return self */
103 }
104
105 int
106 is_private(Crypt::PK::X25519 self)
107 CODE:
108 if (self->key.type == -1) XSRETURN_UNDEF;
109 RETVAL = (self->key.type == PK_PRIVATE) ? 1 : 0;
110 OUTPUT:
111 RETVAL
112
113 SV*
114 key2hash(Crypt::PK::X25519 self)
115 PREINIT:
116 HV *rv_hash;
117 char buf[20001];
118 SV **not_used;
119 CODE:
120 if (self->key.type == -1) XSRETURN_UNDEF;
121 rv_hash = newHV();
122 /* priv */
123 if (self->key.type == PK_PRIVATE) {
124 not_used = hv_store(rv_hash, "priv", 4, newSVpv(self->key.priv, sizeof(self->key.priv)), 0);
125 }
126 else {
127 not_used = hv_store(rv_hash, "priv", 4, &PL_sv_undef, 0);
128 }
129 /* pub */
130 not_used = hv_store(rv_hash, "pub", 3, newSVpv(self->key.pub, sizeof(self->key.pub)), 0);
131 /* algo */
132 not_used = hv_store(rv_hash, "algo", 4, newSVpv("x25519", 0), 0);
133 LTC_UNUSED_PARAM(not_used);
134 RETVAL = newRV_noinc((SV*)rv_hash);
135 OUTPUT:
136 RETVAL
137
138 SV*
139 export_key_der(Crypt::PK::X25519 self, char * type)
140 CODE:
141 {
142 int rv;
143 unsigned char out[4096];
144 unsigned long int out_len = sizeof(out);
145
146 RETVAL = newSVpvn(NULL, 0); /* undef */
147 if (strnEQ(type, "private", 7)) {
148 rv = x25519_export(out, &out_len, PK_PRIVATE, &self->key);
149 if (rv != CRYPT_OK) croak("FATAL: x25519_export(PK_PRIVATE) failed: %s", error_to_string(rv));
150 RETVAL = newSVpvn((char*)out, out_len);
151 }
152 else if (strnEQ(type, "public", 6)) {
153 rv = x25519_export(out, &out_len, PK_PUBLIC|PK_STD, &self->key);
154 if (rv != CRYPT_OK) croak("FATAL: x25519_export(PK_PUBLIC|PK_STD) failed: %s", error_to_string(rv));
155 RETVAL = newSVpvn((char*)out, out_len);
156 }
157 else {
158 croak("FATAL: export_key_der invalid type '%s'", type);
159 }
160 }
161 OUTPUT:
162 RETVAL
163
164 SV *
165 shared_secret(Crypt::PK::X25519 self, Crypt::PK::X25519 pubkey)
166 CODE:
167 {
168 int rv;
169 unsigned char buffer[1024];
170 unsigned long int buffer_len = sizeof(buffer);
171
172 rv = x25519_shared_secret(&self->key, &pubkey->key, buffer, &buffer_len);
173 if (rv != CRYPT_OK) croak("FATAL: x25519_shared_secret failed: %s", error_to_string(rv));
174 RETVAL = newSVpvn((char*)buffer, buffer_len);
175 }
176 OUTPUT:
177 RETVAL
178
179 void
180 DESTROY(Crypt::PK::X25519 self)
181 CODE:
182 Safefree(self);
183
4747 Crypt::PK::DSA T_PTROBJ
4848 Crypt::PK::ECC T_PTROBJ
4949 Crypt::PK::DH T_PTROBJ
50 Crypt::PK::ED25519 T_PTROBJ
51 Crypt::PK::X25519 T_PTROBJ
5052
5153 Math::BigInt::LTM T_PTROBJ
5254