rename Crypt::PK::ED25519 >> Crypt::PK::Ed25519
Karel Miko
4 years ago
152 | 152 | int pindex; |
153 | 153 | curve25519_key key; |
154 | 154 | } ; |
155 | typedef struct curve25519_struct *Crypt__PK__ED25519; /* used by Crypt::PK::ED25519 */ | |
155 | typedef struct curve25519_struct *Crypt__PK__Ed25519; /* used by Crypt::PK::Ed25519 */ | |
156 | 156 | typedef struct curve25519_struct *Crypt__PK__X25519; /* used by Crypt::PK::X25519 */ |
157 | 157 | |
158 | 158 | int mp_tohex_with_leading_zero(mp_int * a, char *str, int maxlen, int minlen) { |
754 | 754 | INCLUDE: inc/CryptX_PK_DSA.xs.inc |
755 | 755 | INCLUDE: inc/CryptX_PK_DH.xs.inc |
756 | 756 | INCLUDE: inc/CryptX_PK_ECC.xs.inc |
757 | INCLUDE: inc/CryptX_PK_ED25519.xs.inc | |
757 | INCLUDE: inc/CryptX_PK_Ed25519.xs.inc | |
758 | 758 | INCLUDE: inc/CryptX_PK_X25519.xs.inc |
759 | 759 | |
760 | 760 | INCLUDE: inc/CryptX_KeyDerivation.xs.inc |
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::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 |