Package list libcryptx-perl / 203caba
ECC improvements Karel Miko 3 years ago
129 changed file(s) with 5046 addition(s) and 3757 deletion(s). Raw diff Collapse all Expand all
00 Changes for CryptX
1
2 0.059 2018-03-XX
3 - new: Crypt::PK::ECC - sign_hash_rfc7518 + verify_hash_rfc7518
14
25 0.058 2018-02-27
36 - fix: decode_b58b + invalid input
135135 prng_state pstate;
136136 int pindex;
137137 ecc_key key;
138 ltc_ecc_set_type dp;
139138 } *Crypt__PK__ECC;
140139
141 int str_add_leading_zero(char *str, int maxlen, int minlen) {
142 int len;
140 int mp_tohex_with_leading_zero(mp_int * a, char *str, int maxlen, int minlen) {
141 int len, rv;
142
143 if (mp_isneg(a) == MP_YES) {
144 *str = '\0';
145 return MP_VAL;
146 }
147
148 rv = mp_toradix_n(a, str, 16, maxlen);
149 if (rv != MP_OKAY) {
150 *str = '\0';
151 return rv;
152 }
153
143154 len = (int)strlen(str);
144155 if (len > 0 && len % 2 && len < maxlen-2) {
145156 memmove(str+1, str, len+1); /* incl. NUL byte */
146157 *str = '0'; /* add leading zero */
147158 }
159
148160 len = (int)strlen(str);
149161 if (len < minlen && minlen < maxlen-1) {
150162 memmove(str+(minlen-len), str, len+1); /* incl. NUL byte */
151163 memset(str, '0', minlen-len); /* add leading zero */
152164 }
165
153166 return MP_OKAY;
154 }
155
156 int mp_tohex_with_leading_zero(mp_int * a, char *str, int maxlen, int minlen) {
157 int rv;
158 if (mp_isneg(a) == MP_YES) {
159 *str = '\0';
160 return MP_VAL;
161 }
162 rv = mp_toradix_n(a, str, 16, maxlen);
163 if (rv != MP_OKAY) {
164 *str = '\0';
165 return rv;
166 }
167 return str_add_leading_zero(str, maxlen, minlen);
168167 }
169168
170169 int _base16_encode(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen)
247246 return obj;
248247 }
249248
250 ltc_ecc_set_type* _ecc_set_dp_from_SV(ltc_ecc_set_type *dp, SV *curve)
249 void _ecc_oid_lookup(ecc_key *key)
250 {
251 int err;
252 unsigned i;
253 void *tmp;
254 const ltc_ecc_set_type *set;
255
256 key->dp.oidlen = 0;
257 if ((err = ltc_mp.init(&tmp)) != CRYPT_OK) return;
258 for (set = ltc_ecc_sets; set->name != NULL; set++) {
259 if ((err = mp_read_radix(tmp, set->prime, 16)) != CRYPT_OK) continue;
260 if ((mp_cmp(tmp, key->dp.prime) != LTC_MP_EQ)) continue;
261 if ((err = mp_read_radix(tmp, set->order, 16)) != CRYPT_OK) continue;
262 if ((mp_cmp(tmp, key->dp.order) != LTC_MP_EQ)) continue;
263 if ((err = mp_read_radix(tmp, set->A, 16)) != CRYPT_OK) continue;
264 if ((mp_cmp(tmp, key->dp.A) != LTC_MP_EQ)) continue;
265 if ((err = mp_read_radix(tmp, set->B, 16)) != CRYPT_OK) continue;
266 if ((mp_cmp(tmp, key->dp.B) != LTC_MP_EQ)) continue;
267 if ((err = mp_read_radix(tmp, set->Gx, 16)) != CRYPT_OK) continue;
268 if ((mp_cmp(tmp, key->dp.base.x) != LTC_MP_EQ)) continue;
269 if ((err = mp_read_radix(tmp, set->Gy, 16)) != CRYPT_OK) continue;
270 if ((mp_cmp(tmp, key->dp.base.y) != LTC_MP_EQ)) continue;
271 if (key->dp.cofactor != set->cofactor) continue;
272 break; /* found */
273 }
274 ltc_mp.deinit(tmp);
275 if (set->name != NULL) {
276 key->dp.oidlen = set->oidlen;
277 for(i = 0; i < set->oidlen; i++) key->dp.oid[i] = set->oid[i];
278 }
279 }
280
281 int _ecc_set_dp_from_SV(ecc_key *key, SV *curve)
251282 {
252283 dTHX; /* fetch context */
253 HV *h;
254 SV *param, **pref;
255 SV **sv_cofactor, **sv_prime, **sv_A, **sv_B, **sv_order, **sv_Gx, **sv_Gy;
284 HV *hc, *hl, *h;
285 SV *sv_crv, **pref;
286 SV **sv_cofactor, **sv_prime, **sv_A, **sv_B, **sv_order, **sv_Gx, **sv_Gy, **sv_oid;
287 char *ch_name;
288 STRLEN l_name, i, j;
256289 int err;
257 char *ch_name;
258 STRLEN l_name;
290
291 if (!SvOK(curve)) croak("FATAL: undefined curve");
259292
260293 if (SvPOK(curve)) {
294 /* string */
261295 ch_name = SvPV(curve, l_name);
262 if ((h = get_hv("Crypt::PK::ECC::curve", 0)) == NULL) croak("FATAL: generate_key_ex: no curve register");
263 if ((pref = hv_fetch(h, ch_name, (U32)l_name, 0)) == NULL) croak("FATAL: generate_key_ex: unknown curve/1 '%s'", ch_name);
264 if (!SvOK(*pref)) croak("FATAL: generate_key_ex: unknown curve/2 '%s'", ch_name);
265 param = *pref;
296 if ((hl = get_hv("Crypt::PK::ECC::curve2ltc", 0)) == NULL) croak("FATAL: no curve2ltc register");
297 pref = hv_fetch(hl, ch_name, (U32)l_name, 0);
298 if (pref && SvOK(*pref)) {
299 sv_crv = *pref; /* found in %cutve2ltc */
300 }
301 else {
302 if ((hc = get_hv("Crypt::PK::ECC::curve", 0)) == NULL) croak("FATAL: no curve register");
303 pref = hv_fetch(hc, ch_name, (U32)l_name, 0);
304 if (pref && SvOK(*pref)) {
305 sv_crv = *pref; /* found in %curve */
306 }
307 else {
308 sv_crv = curve;
309 }
310 }
266311 }
267312 else if (SvROK(curve)) {
268 param = curve;
313 /* hashref */
314 sv_crv = curve;
269315 }
270316 else {
271317 croak("FATAL: curve has to be a string or a hashref");
272318 }
273319
274 if ((h = (HV*)(SvRV(param))) == NULL) croak("FATAL: ecparams: param is not valid hashref");
275
276 if ((sv_prime = hv_fetchs(h, "prime", 0)) == NULL) croak("FATAL: ecparams: missing param prime");
277 if ((sv_A = hv_fetchs(h, "A", 0)) == NULL) croak("FATAL: ecparams: missing param A");
278 if ((sv_B = hv_fetchs(h, "B", 0)) == NULL) croak("FATAL: ecparams: missing param B");
279 if ((sv_order = hv_fetchs(h, "order", 0)) == NULL) croak("FATAL: ecparams: missing param order");
280 if ((sv_Gx = hv_fetchs(h, "Gx", 0)) == NULL) croak("FATAL: ecparams: missing param Gx");
281 if ((sv_Gy = hv_fetchs(h, "Gy", 0)) == NULL) croak("FATAL: ecparams: missing param Gy");
282 if ((sv_cofactor = hv_fetchs(h, "cofactor", 0)) == NULL) croak("FATAL: ecparams: missing param cofactor");
283
284 if (!SvOK(*sv_prime )) croak("FATAL: ecparams: undefined param prime");
285 if (!SvOK(*sv_A )) croak("FATAL: ecparams: undefined param A");
286 if (!SvOK(*sv_B )) croak("FATAL: ecparams: undefined param B");
287 if (!SvOK(*sv_order )) croak("FATAL: ecparams: undefined param order");
288 if (!SvOK(*sv_Gx )) croak("FATAL: ecparams: undefined param Gx");
289 if (!SvOK(*sv_Gy )) croak("FATAL: ecparams: undefined param Gy");
290 if (!SvOK(*sv_cofactor)) croak("FATAL: ecparams: undefined param cofactor");
291
292 err = ecc_dp_set( dp,
293 SvPV_nolen(*sv_prime),
294 SvPV_nolen(*sv_A),
295 SvPV_nolen(*sv_B),
296 SvPV_nolen(*sv_order),
297 SvPV_nolen(*sv_Gx),
298 SvPV_nolen(*sv_Gy),
299 (unsigned long)SvUV(*sv_cofactor),
300 NULL, /* we intentionally don't allow setting custom names */
301 NULL /* we intentionally don't allow setting custom OIDs */
302 );
303 return err == CRYPT_OK ? dp : NULL;
304 }
305
306 void _ecc_free_key(ecc_key *key, ltc_ecc_set_type *dp)
307 {
308 if(dp) {
309 ecc_dp_clear(dp);
310 }
311 if (key->type != -1) {
312 ecc_free(key);
313 key->type = -1;
314 key->dp = NULL;
320 if (SvPOK(sv_crv)) {
321 /* string - curve name */
322 const ltc_ecc_set_type *dp;
323 ch_name = SvPV(sv_crv, l_name);
324 if (ecc_get_set_by_name(ch_name, &dp) != CRYPT_OK) croak("FATAL: ecparams: unknown curve '%s'", ch_name);
325 return ecc_set_dp(dp, key);
326 }
327 else {
328 /* hashref */
329 ltc_ecc_set_type set = { 0 };
330
331 if ((h = (HV*)(SvRV(sv_crv))) == NULL) croak("FATAL: ecparams: param is not valid hashref");
332
333 if ((sv_prime = hv_fetchs(h, "prime", 0)) == NULL) croak("FATAL: ecparams: missing param prime");
334 if ((sv_A = hv_fetchs(h, "A", 0)) == NULL) croak("FATAL: ecparams: missing param A");
335 if ((sv_B = hv_fetchs(h, "B", 0)) == NULL) croak("FATAL: ecparams: missing param B");
336 if ((sv_order = hv_fetchs(h, "order", 0)) == NULL) croak("FATAL: ecparams: missing param order");
337 if ((sv_Gx = hv_fetchs(h, "Gx", 0)) == NULL) croak("FATAL: ecparams: missing param Gx");
338 if ((sv_Gy = hv_fetchs(h, "Gy", 0)) == NULL) croak("FATAL: ecparams: missing param Gy");
339 if ((sv_cofactor = hv_fetchs(h, "cofactor", 0)) == NULL) croak("FATAL: ecparams: missing param cofactor");
340
341 if (!SvOK(*sv_prime )) croak("FATAL: ecparams: undefined param prime");
342 if (!SvOK(*sv_A )) croak("FATAL: ecparams: undefined param A");
343 if (!SvOK(*sv_B )) croak("FATAL: ecparams: undefined param B");
344 if (!SvOK(*sv_order )) croak("FATAL: ecparams: undefined param order");
345 if (!SvOK(*sv_Gx )) croak("FATAL: ecparams: undefined param Gx");
346 if (!SvOK(*sv_Gy )) croak("FATAL: ecparams: undefined param Gy");
347 if (!SvOK(*sv_cofactor)) croak("FATAL: ecparams: undefined param cofactor");
348
349 set.prime = SvPV_nolen(*sv_prime);
350 set.A = SvPV_nolen(*sv_A);
351 set.B = SvPV_nolen(*sv_B);
352 set.order = SvPV_nolen(*sv_order);
353 set.Gx = SvPV_nolen(*sv_Gx);
354 set.Gy = SvPV_nolen(*sv_Gy);
355 set.cofactor = (unsigned long)SvUV(*sv_cofactor),
356 set.name = NULL;
357 set.oidlen = 0;
358
359 sv_oid = hv_fetchs(h, "oid", 0);
360 if (sv_oid && SvPOK(*sv_oid)) {
361 ch_name = SvPV(*sv_oid, l_name);
362 for (i = 0, j = 0; i < l_name; i++) {
363 if (ch_name[i] == '.') {
364 if (++j >= 16) return CRYPT_ERROR;
365 }
366 else if(ch_name[i] >= '0' && ch_name[i] <= '9') {
367 set.oid[j] = set.oid[j] * 10 + (ch_name[i] - '0');
368 }
369 else {
370 return CRYPT_ERROR;
371 }
372 }
373 if (j == 0) return CRYPT_ERROR;
374 set.oidlen = j + 1;
375 }
376
377 if ((err = ecc_set_dp(&set, key)) != CRYPT_OK) return err;
378 if (key->dp.oidlen == 0) _ecc_oid_lookup(key);
379 return CRYPT_OK;
315380 }
316381 }
317382
1010 if (!RETVAL) croak("FATAL: Newz failed");
1111 RETVAL->pindex = find_prng("chacha20");
1212 RETVAL->key.type = -1;
13 ecc_dp_init(&RETVAL->dp);
1413 if (RETVAL->pindex == -1) {
1514 Safefree(RETVAL);
1615 croak("FATAL: find_prng('chacha20') failed");
3029 {
3130 int rv;
3231 /* setup dp structure */
33 _ecc_set_dp_from_SV(&self->dp, curve); /* croaks on error */
32 rv = _ecc_set_dp_from_SV(&self->key, curve); /* croaks on error */
33 if (rv != CRYPT_OK) croak("FATAL: ecc_set_dp failed: %s", error_to_string(rv));
3434 /* gen the key */
35 rv = ecc_make_key_ex(&self->pstate, self->pindex, &self->key, &self->dp);
36 if (rv != CRYPT_OK) croak("FATAL: ecc_make_key_ex failed: %s", error_to_string(rv));
35 rv = ecc_generate_key(&self->pstate, self->pindex, &self->key);
36 if (rv != CRYPT_OK) croak("FATAL: ecc_generate_key failed: %s", error_to_string(rv));
3737 XPUSHs(ST(0)); /* return self */
3838 }
3939
4646 STRLEN data_len=0;
4747
4848 data = (unsigned char *)SvPVbyte(key_data, data_len);
49 _ecc_free_key(&self->key, &self->dp);
50 rv = ecc_import_full(data, (unsigned long)data_len, &self->key, &self->dp);
51 if (rv != CRYPT_OK) croak("FATAL: ecc_import_full failed: %s", error_to_string(rv));
49 if (self->key.type != -1) { ecc_free(&self->key); self->key.type = -1; }
50 rv = ecc_import_openssl(data, (unsigned long)data_len, &self->key);
51 if (rv != CRYPT_OK) croak("FATAL: ecc_import_openssl failed: %s", error_to_string(rv));
5252 XPUSHs(ST(0)); /* return self */
5353 }
5454
6464 if (SvOK(passwd)) {
6565 pwd = (unsigned char *)SvPVbyte(passwd, pwd_len);
6666 }
67 _ecc_free_key(&self->key, &self->dp);
68 rv = ecc_import_pkcs8(data, (unsigned long)data_len, pwd, (unsigned long)pwd_len, &self->key, &self->dp);
67 if (self->key.type != -1) { ecc_free(&self->key); self->key.type = -1; }
68 rv = ecc_import_pkcs8(data, (unsigned long)data_len, pwd, (unsigned long)pwd_len, &self->key);
6969 if (rv != CRYPT_OK) croak("FATAL: ecc_import_pkcs8 failed: %s", error_to_string(rv));
7070 XPUSHs(ST(0)); /* return self */
7171 }
7272
7373 void
74 _import_x509(Crypt::PK::ECC self, SV * key_data)
75 PPCODE:
76 {
77 int rv;
78 unsigned char *data=NULL;
79 STRLEN data_len=0;
80
81 data = (unsigned char *)SvPVbyte(key_data, data_len);
82 if (self->key.type != -1) { ecc_free(&self->key); self->key.type = -1; }
83 rv = ecc_import_x509(data, (unsigned long)data_len, &self->key);
84 if (rv != CRYPT_OK) croak("FATAL: ecc_import_x509 failed: %s", error_to_string(rv));
85 XPUSHs(ST(0)); /* return self */
86 }
87
88 void
7489 import_key_raw(Crypt::PK::ECC self, SV * key_data, SV * curve)
7590 PPCODE:
7691 {
77 int rv;
92 int rv, type;
7893 unsigned char *data=NULL;
7994 STRLEN data_len=0;
8095
8196 data = (unsigned char *)SvPVbyte(key_data, data_len);
82 _ecc_free_key(&self->key, &self->dp);
83
84 _ecc_set_dp_from_SV(&self->dp, curve); /* croaks on error */
85
86 rv = ecc_import_raw(data, (unsigned long)data_len, &self->key, &self->dp);
87 if (rv != CRYPT_OK) croak("FATAL: ecc_import_raw failed: %s", error_to_string(rv));
97 if (self->key.type != -1) { ecc_free(&self->key); self->key.type = -1; }
98 /* setup dp structure */
99 rv = _ecc_set_dp_from_SV(&self->key, curve); /* croaks on error */
100 if (rv != CRYPT_OK) croak("FATAL: ecc_set_dp failed: %s", error_to_string(rv));
101 /* import key */
102 type = (data_len == (STRLEN)ecc_get_size(&self->key)) ? PK_PRIVATE : PK_PUBLIC;
103 rv = ecc_set_key(data, (unsigned long)data_len, type, &self->key);
104 if (rv != CRYPT_OK) croak("FATAL: ecc_set_key failed: %s", error_to_string(rv));
88105 XPUSHs(ST(0)); /* return self */
89106 }
90107
152169 not_used = hv_store(rv_hash, "pub_y", 5, newSVpv("", 0), 0);
153170 }
154171 /* curve_... */
155 if (self->key.dp) {
156 not_used = hv_store(rv_hash, "curve_cofactor", 14, newSViv(self->key.dp->cofactor), 0);
157 /* prepend leading zero if we have odd number of hexadecimal digits */
158 strncpy(buf, self->key.dp->prime, 20000); str_add_leading_zero(buf, 20000, 0);
159 not_used = hv_store(rv_hash, "curve_prime", 11, newSVpv(buf, strlen(buf)), 0);
160 strncpy(buf, self->key.dp->A, 20000); str_add_leading_zero(buf, 20000, 0);
161 not_used = hv_store(rv_hash, "curve_A", 7, newSVpv(buf, strlen(buf)), 0);
162 strncpy(buf, self->key.dp->B, 20000); str_add_leading_zero(buf, 20000, 0);
163 not_used = hv_store(rv_hash, "curve_B", 7, newSVpv(buf, strlen(buf)), 0);
164 strncpy(buf, self->key.dp->order, 20000); str_add_leading_zero(buf, 20000, 0);
165 not_used = hv_store(rv_hash, "curve_order", 11, newSVpv(buf, strlen(buf)), 0);
166 strncpy(buf, self->key.dp->Gx, 20000); str_add_leading_zero(buf, 20000, 0);
167 not_used = hv_store(rv_hash, "curve_Gx", 8, newSVpv(buf, strlen(buf)), 0);
168 strncpy(buf, self->key.dp->Gy, 20000); str_add_leading_zero(buf, 20000, 0);
169 not_used = hv_store(rv_hash, "curve_Gy", 8, newSVpv(buf, strlen(buf)), 0);
170 /* OLD approach
171 not_used = hv_store(rv_hash, "curve_prime", 11, newSVpv(self->key.dp->prime, strlen(self->key.dp->prime)), 0);
172 not_used = hv_store(rv_hash, "curve_A", 7, newSVpv(self->key.dp->A, strlen(self->key.dp->A)), 0);
173 not_used = hv_store(rv_hash, "curve_B", 7, newSVpv(self->key.dp->B, strlen(self->key.dp->B)), 0);
174 not_used = hv_store(rv_hash, "curve_order", 11, newSVpv(self->key.dp->order, strlen(self->key.dp->order)), 0);
175 not_used = hv_store(rv_hash, "curve_Gx", 8, newSVpv(self->key.dp->Gx, strlen(self->key.dp->Gx)), 0);
176 not_used = hv_store(rv_hash, "curve_Gy", 8, newSVpv(self->key.dp->Gy, strlen(self->key.dp->Gy)), 0);
177 */
178 {
179 mp_int p_num;
180 mp_init(&p_num);
181 mp_read_radix(&p_num, self->key.dp->prime, 16);
182 not_used = hv_store(rv_hash, "curve_bytes", 11, newSViv(mp_unsigned_bin_size(&p_num)), 0);
183 not_used = hv_store(rv_hash, "curve_bits", 10, newSViv(mp_count_bits(&p_num)), 0);
184 mp_clear(&p_num);
185 }
186 {
172 {
173 not_used = hv_store(rv_hash, "curve_cofactor", 14, newSViv(self->key.dp.cofactor), 0);
174 mp_tohex_with_leading_zero(self->key.dp.prime, buf, 20000, 0);
175 not_used = hv_store(rv_hash, "curve_prime", 11, newSVpv(buf, strlen(buf)), 0);
176 mp_tohex_with_leading_zero(self->key.dp.A, buf, 20000, 0);
177 not_used = hv_store(rv_hash, "curve_A", 7, newSVpv(buf, strlen(buf)), 0);
178 mp_tohex_with_leading_zero(self->key.dp.B, buf, 20000, 0);
179 not_used = hv_store(rv_hash, "curve_B", 7, newSVpv(buf, strlen(buf)), 0);
180 mp_tohex_with_leading_zero(self->key.dp.order, buf, 20000, 0);
181 not_used = hv_store(rv_hash, "curve_order", 11, newSVpv(buf, strlen(buf)), 0);
182 mp_tohex_with_leading_zero(self->key.dp.base.x, buf, 20000, 0);
183 not_used = hv_store(rv_hash, "curve_Gx", 8, newSVpv(buf, strlen(buf)), 0);
184 mp_tohex_with_leading_zero(self->key.dp.base.y, buf, 20000, 0);
185 not_used = hv_store(rv_hash, "curve_Gy", 8, newSVpv(buf, strlen(buf)), 0);
186 not_used = hv_store(rv_hash, "curve_bytes", 11, newSViv(mp_unsigned_bin_size(self->key.dp.prime)), 0);
187 not_used = hv_store(rv_hash, "curve_bits", 10, newSViv(mp_count_bits(self->key.dp.prime)), 0);
188
189 if (self->key.dp.oidlen > 0) {
187190 unsigned long i;
188 SV *name;
189 char *name_ptr;
190 STRLEN name_len;
191
192 name = newSVpv(self->key.dp->name, strlen(self->key.dp->name));
193 name_ptr = SvPV(name, name_len);
194 for (i=0; i<name_len && name_ptr[i]>0; i++) name_ptr[i] = toLOWER(name_ptr[i]);
195 not_used = hv_store(rv_hash, "curve_name", 10, name, 0);
196 }
197 if (self->key.dp->oid.OIDlen > 0) {
198 unsigned long i;
191 HV *h;
192 SV **pref, *cname;
193 char *cname_ptr, *oid_ptr;
194 STRLEN cname_len;
195
196 /* OID -> "curve_oid" */
199197 SV *oid = newSVpv("", 0);
200 for(i = 0; i < self->key.dp->oid.OIDlen - 1; i++) sv_catpvf(oid, "%lu.", self->key.dp->oid.OID[i]);
201 sv_catpvf(oid, "%lu", self->key.dp->oid.OID[i]);
198 for(i = 0; i < self->key.dp.oidlen - 1; i++) sv_catpvf(oid, "%lu.", self->key.dp.oid[i]);
199 sv_catpvf(oid, "%lu", self->key.dp.oid[i]);
200 oid_ptr = SvPVX(oid);
202201 not_used = hv_store(rv_hash, "curve_oid", 9, oid, 0);
202
203 /* curve name -> "curve_name" */
204 if ((h = get_hv("Crypt::PK::ECC::curve2ltc", 0)) != NULL) {
205 pref = hv_fetch(h, oid_ptr, (U32)strlen(oid_ptr), 0);
206 if (pref) {
207 cname_ptr = SvPV(*pref, cname_len);
208 cname = newSVpv(cname_ptr, cname_len);
209 cname_ptr = SvPVX(cname);
210 for (i=0; i<cname_len && cname_ptr[i]>0; i++) cname_ptr[i] = toLOWER(cname_ptr[i]);
211 not_used = hv_store(rv_hash, "curve_name", 10, cname, 0);
212 }
213 }
203214 }
204215 }
205216 /* size */
219230 unsigned char out[4096];
220231 unsigned long int out_len = 4096;
221232
222 RETVAL = newSVpvn(NULL, 0); /* undef */
233 if (self->key.type == -1) croak("FATAL: export_key_der no key");
223234 if (strnEQ(type, "private_short", 16)) {
224 rv = ecc_export_full(out, &out_len, PK_PRIVATE|PK_CURVEOID, &self->key);
225 if (rv != CRYPT_OK) croak("FATAL: ecc_export(PK_PRIVATE|PK_CURVEOID) failed: %s", error_to_string(rv));
235 rv = ecc_export_openssl(out, &out_len, PK_PRIVATE|PK_CURVEOID, &self->key);
236 if (rv != CRYPT_OK) croak("FATAL: ecc_export_openssl(PK_PRIVATE|PK_CURVEOID) failed: %s", error_to_string(rv));
237 RETVAL = newSVpvn((char*)out, out_len);
238 }
239 else if (strnEQ(type, "private_compressed", 16)) {
240 rv = ecc_export_openssl(out, &out_len, PK_PRIVATE|PK_CURVEOID|PK_COMPRESSED, &self->key);
241 if (rv != CRYPT_OK) croak("FATAL: ecc_export_openssl(PK_PRIVATE|PK_CURVEOID|PK_COMPRESSED) failed: %s", error_to_string(rv));
226242 RETVAL = newSVpvn((char*)out, out_len);
227243 }
228244 else if (strnEQ(type, "private", 7)) {
229 rv = ecc_export_full(out, &out_len, PK_PRIVATE, &self->key);
230 if (rv != CRYPT_OK) croak("FATAL: ecc_export(PK_PRIVATE) failed: %s", error_to_string(rv));
245 rv = ecc_export_openssl(out, &out_len, PK_PRIVATE, &self->key);
246 if (rv != CRYPT_OK) croak("FATAL: ecc_export_openssl(PK_PRIVATE) failed: %s", error_to_string(rv));
247 RETVAL = newSVpvn((char*)out, out_len);
248 }
249 else if (strnEQ(type, "public_compressed", 15)) {
250 rv = ecc_export_openssl(out, &out_len, PK_PUBLIC|PK_CURVEOID|PK_COMPRESSED, &self->key);
251 if (rv != CRYPT_OK) croak("FATAL: ecc_export_openssl(PK_PUBLIC|PK_CURVEOID|PK_COMPRESSED) failed: %s", error_to_string(rv));
231252 RETVAL = newSVpvn((char*)out, out_len);
232253 }
233254 else if (strnEQ(type, "public_short", 15)) {
234 rv = ecc_export_full(out, &out_len, PK_PUBLIC|PK_CURVEOID, &self->key);
235 if (rv != CRYPT_OK) croak("FATAL: ecc_export(PK_PUBLIC|PK_CURVEOID) failed: %s", error_to_string(rv));
255 rv = ecc_export_openssl(out, &out_len, PK_PUBLIC|PK_CURVEOID, &self->key);
256 if (rv != CRYPT_OK) croak("FATAL: ecc_export_openssl(PK_PUBLIC|PK_CURVEOID) failed: %s", error_to_string(rv));
236257 RETVAL = newSVpvn((char*)out, out_len);
237258 }
238259 else if (strnEQ(type, "public", 6)) {
239 rv = ecc_export_full(out, &out_len, PK_PUBLIC, &self->key);
240 if (rv != CRYPT_OK) croak("FATAL: ecc_export(PK_PUBLIC) failed: %s", error_to_string(rv));
260 rv = ecc_export_openssl(out, &out_len, PK_PUBLIC, &self->key);
261 if (rv != CRYPT_OK) croak("FATAL: ecc_export_openssl(PK_PUBLIC) failed: %s", error_to_string(rv));
241262 RETVAL = newSVpvn((char*)out, out_len);
242263 }
243264 else {
255276 unsigned char out[4096];
256277 unsigned long int out_len = sizeof(out);
257278
258 RETVAL = newSVpvn(NULL, 0); /* undef */
279 if (self->key.type == -1) croak("FATAL: export_key_der no key");
259280 if (strnEQ(type, "private", 7)) {
260 rv = ecc_export_raw(out, &out_len, PK_PRIVATE, &self->key);
261 if (rv != CRYPT_OK) croak("FATAL: ecc_export_raw(private) failed: %s", error_to_string(rv));
281 rv = ecc_get_key(out, &out_len, PK_PRIVATE, &self->key);
282 if (rv != CRYPT_OK) croak("FATAL: ecc_get_key(private) failed: %s", error_to_string(rv));
262283 RETVAL = newSVpvn((char*)out, out_len);
263284 }
264285 else if (strnEQ(type, "public_compressed", 17)) {
265 rv = ecc_export_raw(out, &out_len, PK_PUBLIC|PK_COMPRESSED, &self->key);
266 if (rv != CRYPT_OK) croak("FATAL: ecc_export_raw(public_compressed) failed: %s", error_to_string(rv));
286 rv = ecc_get_key(out, &out_len, PK_PUBLIC|PK_COMPRESSED, &self->key);
287 if (rv != CRYPT_OK) croak("FATAL: ecc_get_key(public_compressed) failed: %s", error_to_string(rv));
267288 RETVAL = newSVpvn((char*)out, out_len);
268289 }
269290 else if (strnEQ(type, "public", 6)) {
270 rv = ecc_export_raw(out, &out_len, PK_PUBLIC, &self->key);
271 if (rv != CRYPT_OK) croak("FATAL: ecc_export_raw(public) failed: %s", error_to_string(rv));
291 rv = ecc_get_key(out, &out_len, PK_PUBLIC, &self->key);
292 if (rv != CRYPT_OK) croak("FATAL: ecc_get_key(public) failed: %s", error_to_string(rv));
272293 RETVAL = newSVpvn((char*)out, out_len);
273294 }
274295 else {
323344 SV *
324345 sign_hash(Crypt::PK::ECC self, SV * data, const char * hash_name = "SHA1")
325346 ALIAS:
347 sign_hash_rfc7518 = 3
326348 sign_message = 1
327349 sign_message_rfc7518 = 2
328350 CODE:
341363 data_ptr = tmp;
342364 data_len = tmp_len;
343365 }
344 if (ix == 2) {
366 if (ix == 2 || ix == 3) {
345367 rv = ecc_sign_hash_rfc7518(data_ptr, (unsigned long)data_len, buffer, &buffer_len,
346368 &self->pstate, self->pindex,
347369 &self->key);
360382 int
361383 verify_hash(Crypt::PK::ECC self, SV * sig, SV * data, const char * hash_name = "SHA1")
362384 ALIAS:
385 verify_hash_rfc7518 = 3
363386 verify_message = 1
364387 verify_message_rfc7518 = 2
365388 CODE:
381404 }
382405 RETVAL = 1;
383406 stat = 0;
384 if (ix == 2) {
407 if (ix == 2 || ix == 3) {
385408 rv = ecc_verify_hash_rfc7518(sig_ptr, (unsigned long)sig_len, data_ptr, (unsigned long)data_len, &stat, &self->key);
386409 }
387410 else {
410433 void
411434 DESTROY(Crypt::PK::ECC self)
412435 CODE:
413 _ecc_free_key(&self->key, &self->dp);
436 if (self->key.type != -1) { ecc_free(&self->key); self->key.type = -1; }
414437 Safefree(self);
415438
99 our @EXPORT = qw();
1010
1111 use Carp;
12 $Carp::Internal{(__PACKAGE__)}++;
1213 use CryptX;
1314 use Crypt::Digest qw(digest_data digest_data_b64u);
1415 use Crypt::Misc qw(read_rawfile encode_b64u decode_b64u encode_b64 decode_b64 pem_to_der der_to_pem);
1516 use Crypt::PK;
1617
1718 our %curve = (
18 ### http://www.ecc-brainpool.org/download/Domain-parameters.pdf (v1.0 19.10.2005)
19 brainpoolp160r1 => {
20 oid => '1.3.36.3.3.2.8.1.1.1',
21 prime => "E95E4A5F737059DC60DFC7AD95B3D8139515620F",
22 A => "340E7BE2A280EB74E2BE61BADA745D97E8F7C300",
23 B => "1E589A8595423412134FAA2DBDEC95C8D8675E58",
24 Gx => "BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3",
25 Gy => "1667CB477A1A8EC338F94741669C976316DA6321",
26 order => "E95E4A5F737059DC60DF5991D45029409E60FC09",
27 cofactor => 1,
19 # extra curves not recognized by libtomcrypt
20 'wap-wsg-idm-ecid-wtls8' => {
21 prime => "FFFFFFFFFFFFFFFFFFFFFFFFFDE7",
22 A => "0000000000000000000000000000",
23 B => "0000000000000000000000000003",
24 order => "0100000000000001ECEA551AD837E9",
25 Gx => "0000000000000000000000000001",
26 Gy => "0000000000000000000000000002",
27 cofactor => 1,
28 oid => '2.23.43.1.4.8',
2829 },
29 brainpoolp192r1 => {
30 oid => '1.3.36.3.3.2.8.1.1.3',
31 prime => "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297",
32 A => "6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF",
33 B => "469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9",
34 Gx => "C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6",
35 Gy => "14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F",
36 order => "C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1",
37 cofactor => 1,
38 },
39 brainpoolp224r1 => {
40 oid => '1.3.36.3.3.2.8.1.1.5',
41 prime => "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF",
42 A => "68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43",
43 B => "2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B",
44 Gx => "0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D",
45 Gy => "58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD",
46 order => "D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F",
47 cofactor => 1,
48 },
49 brainpoolp256r1 => {
50 oid => '1.3.36.3.3.2.8.1.1.7',
51 prime => "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377",
52 A => "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9",
53 B => "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6",
54 Gx => "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262",
55 Gy => "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997",
56 order => "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7",
57 cofactor => 1,
58 },
59 brainpoolp320r1 => {
60 oid => '1.3.36.3.3.2.8.1.1.9',
61 prime => "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27",
62 A => "3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4",
63 B => "520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6",
64 Gx => "43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E20611",
65 Gy => "14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1",
66 order => "D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311",
67 cofactor => 1,
68 },
69 brainpoolp384r1 => {
70 oid => '1.3.36.3.3.2.8.1.1.11',
71 prime => "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53",
72 A => "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826",
73 B => "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11",
74 Gx => "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E",
75 Gy => "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315",
76 order => "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565",
77 cofactor => 1,
78 },
79 brainpoolp512r1 => {
80 oid => '1.3.36.3.3.2.8.1.1.13',
81 prime => "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3",
82 A => "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA",
83 B => "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723",
84 Gx => "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822",
85 Gy => "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892",
86 order => "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069",
87 cofactor => 1,
88 },
89 ### http://www.secg.org/collateral/sec2_final.pdf (September 20, 2000 - Version 1.0)
90 secp112r1 => {
91 oid => '1.3.132.0.6',
92 prime => "DB7C2ABF62E35E668076BEAD208B",
93 A => "DB7C2ABF62E35E668076BEAD2088",
94 B => "659EF8BA043916EEDE8911702B22",
95 Gx => "09487239995A5EE76B55F9C2F098",
96 Gy => "A89CE5AF8724C0A23E0E0FF77500",
97 order => "DB7C2ABF62E35E7628DFAC6561C5",
98 cofactor => 1,
99 },
100 secp112r2 => {
101 oid => '1.3.132.0.7',
102 prime => "DB7C2ABF62E35E668076BEAD208B",
103 A => "6127C24C05F38A0AAAF65C0EF02C",
104 B => "51DEF1815DB5ED74FCC34C85D709",
105 Gx => "4BA30AB5E892B4E1649DD0928643",
106 Gy => "ADCD46F5882E3747DEF36E956E97",
107 order => "36DF0AAFD8B8D7597CA10520D04B",
108 cofactor => 4,
109 },
110 secp128r1 => {
111 oid => '1.3.132.0.28',
112 prime => "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF",
113 A => "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC",
114 B => "E87579C11079F43DD824993C2CEE5ED3",
115 Gx => "161FF7528B899B2D0C28607CA52C5B86",
116 Gy => "CF5AC8395BAFEB13C02DA292DDED7A83",
117 order => "FFFFFFFE0000000075A30D1B9038A115",
118 cofactor => 1,
119 },
120 secp128r2 => {
121 oid => '1.3.132.0.29',
122 prime => "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF",
123 A => "D6031998D1B3BBFEBF59CC9BBFF9AEE1",
124 B => "5EEEFCA380D02919DC2C6558BB6D8A5D",
125 Gx => "7B6AA5D85E572983E6FB32A7CDEBC140",
126 Gy => "27B6916A894D3AEE7106FE805FC34B44",
127 order => "3FFFFFFF7FFFFFFFBE0024720613B5A3",
128 cofactor => 4,
129 },
130 secp160k1 => {
131 oid => '1.3.132.0.9',
132 prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73",
133 A => "0000000000000000000000000000000000000000",
134 B => "0000000000000000000000000000000000000007",
135 Gx => "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB",
136 Gy => "938CF935318FDCED6BC28286531733C3F03C4FEE",
137 order => "0100000000000000000001B8FA16DFAB9ACA16B6B3",
138 cofactor => 1,
139 },
140 secp160r1 => {
141 oid => '1.3.132.0.8',
142 prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF",
143 A => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC",
144 B => "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45",
145 Gx => "4A96B5688EF573284664698968C38BB913CBFC82",
146 Gy => "23A628553168947D59DCC912042351377AC5FB32",
147 order => "0100000000000000000001F4C8F927AED3CA752257",
148 cofactor => 1,
149 },
150 secp160r2 => {
151 oid => '1.3.132.0.30',
152 prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73",
153 A => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70",
154 B => "B4E134D3FB59EB8BAB57274904664D5AF50388BA",
155 Gx => "52DCB034293A117E1F4FF11B30F7199D3144CE6D",
156 Gy => "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E",
157 order => "0100000000000000000000351EE786A818F3A1A16B",
158 cofactor => 1,
159 },
160 secp192k1 => {
161 oid => '1.3.132.0.31',
162 prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37",
163 A => "000000000000000000000000000000000000000000000000",
164 B => "000000000000000000000000000000000000000000000003",
165 Gx => "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D",
166 Gy => "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D",
167 order => "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D",
168 cofactor => 1,
169 },
170 secp192r1 => { # == NIST P-192, X9.62 prime192v1
171 oid => '1.2.840.10045.3.1.1',
172 prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
173 A => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
174 B => "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1",
175 Gx => "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012",
176 Gy => "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811",
177 order => "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831",
178 cofactor => 1,
179 },
180 secp224k1 => {
181 oid => '1.3.132.0.32',
182 prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D",
183 A => "00000000000000000000000000000000000000000000000000000000",
184 B => "00000000000000000000000000000000000000000000000000000005",
185 Gx => "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C",
186 Gy => "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5",
187 order => "010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7",
188 cofactor => 1,
189 },
190 secp224r1 => { # == NIST P-224
191 oid => '1.3.132.0.33',
192 prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
193 A => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE",
194 B => "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
195 Gx => "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
196 Gy => "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34",
197 order => "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",
198 cofactor => 1,
199 },
200 secp256k1 => {
201 oid => '1.3.132.0.10',
202 prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F",
203 A => "0000000000000000000000000000000000000000000000000000000000000000",
204 B => "0000000000000000000000000000000000000000000000000000000000000007",
205 Gx => "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798",
206 Gy => "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8",
207 order => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141",
208 cofactor => 1,
209 },
210 secp256r1 => { # == NIST P-256, X9.62 prime256v1
211 oid => '1.2.840.10045.3.1.7',
212 prime => "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
213 A => "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC",
214 B => "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B",
215 Gx => "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
216 Gy => "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
217 order => "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551",
218 cofactor => 1,
219 },
220 secp384r1 => { # == NIST P-384
221 oid => '1.3.132.0.34',
222 prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF",
223 A => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC",
224 B => "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF",
225 Gx => "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7",
226 Gy => "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F",
227 order => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973",
228 cofactor => 1,
229 },
230 secp521r1 => { # == NIST P-521
231 oid => '1.3.132.0.35',
232 prime => "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
233 A => "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC",
234 B => "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",
235 Gx => "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66",
236 Gy => "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650",
237 order => "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409",
238 cofactor => 1
239 },
240 ### http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf (July 2013)
241 nistp192 => { # == secp192r1, X9.62 prime192v1
242 oid => '1.2.840.10045.3.1.1',
243 prime => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF',
244 A => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC',
245 B => '64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1',
246 Gx => '188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012',
247 Gy => '07192B95FFC8DA78631011ED6B24CDD573F977A11E794811',
248 order => 'FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831',
249 cofactor => 1,
250 },
251 nistp224 => { # == secp224r1
252 oid => '1.3.132.0.33',
253 prime => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001',
254 A => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE',
255 B => 'B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4',
256 Gx => 'B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21',
257 Gy => 'BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34',
258 order => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D',
259 cofactor => 1,
260 },
261 nistp256 => { # == secp256r1, X9.62 prime256v1
262 oid => '1.2.840.10045.3.1.7',
263 prime => 'FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF',
264 A => 'FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC',
265 B => '5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B',
266 Gx => '6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296',
267 Gy => '4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5',
268 order => 'FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551',
269 cofactor => 1,
270 },
271 nistp384 => { # == secp384r1
272 oid => '1.3.132.0.34',
273 prime => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF',
274 A => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC',
275 B => 'B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF',
276 Gx => 'AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7',
277 Gy => '3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F',
278 order => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973',
279 cofactor => 1,
280 },
281 nistp521 => { # == secp521r1
282 oid => '1.3.132.0.35',
283 prime => '1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF',
284 A => '1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC',
285 B => '051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00',
286 Gx => '0C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66',
287 Gy => '11839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650',
288 order => '1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409',
289 cofactor => 1,
290 },
291 ### ANS X9.62 elliptic curves - http://www.flexiprovider.de/CurvesGfpX962.html
292 prime192v1 => { # == secp192r1, NIST P-192
293 oid => '1.2.840.10045.3.1.1',
294 prime => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF',
295 A => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC',
296 B => '64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1',
297 Gx => '188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012',
298 Gy => '07192B95FFC8DA78631011ED6B24CDD573F977A11E794811',
299 order => 'FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831',
300 cofactor => 1,
301 },
302 prime192v2 => {
303 oid => '1.2.840.10045.3.1.2',
304 prime => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF',
305 A => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC',
306 B => 'CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953',
307 Gx => 'EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A',
308 Gy => '6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15',
309 order => 'FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31',
310 cofactor => 1
311 },
312 prime192v3 => {
313 oid => '1.2.840.10045.3.1.3',
314 prime => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF',
315 A => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC',
316 B => '22123DC2395A05CAA7423DAECCC94760A7D462256BD56916',
317 Gx => '7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896',
318 Gy => '38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0',
319 order => 'FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13',
320 cofactor => 1,
321 },
322 prime239v1 => {
323 oid => '1.2.840.10045.3.1.4',
324 prime => '7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF',
325 A => '7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC',
326 B => '6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A',
327 Gx => '0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF',
328 Gy => '7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE',
329 order => '7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B',
330 cofactor => 1,
331 },
332 prime239v2 => {
333 oid => '1.2.840.10045.3.1.5',
334 prime => '7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF',
335 A => '7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC',
336 B => '617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C',
337 Gx => '38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7',
338 Gy => '5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA',
339 order => '7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063',
340 cofactor => 1,
341 },
342 prime239v3 => {
343 oid => '1.2.840.10045.3.1.6',
344 prime => '7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF',
345 A => '7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC',
346 B => '255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E',
347 Gx => '6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A',
348 Gy => '1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3',
349 order => '7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551',
350 cofactor => 1,
351 },
352 prime256v1 => { # == secp256r1, NIST P-256
353 oid => '1.2.840.10045.3.1.7',
354 prime => 'FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF',
355 A => 'FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC',
356 B => '5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B',
357 Gx => '6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296',
358 Gy => '4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5',
359 order => 'FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551',
360 cofactor => 1,
30 'wap-wsg-idm-ecid-wtls9' => {
31 prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC808F",
32 A => "0000000000000000000000000000000000000000",
33 B => "0000000000000000000000000000000000000003",
34 order => "0100000000000000000001CDC98AE0E2DE574ABF33",
35 Gx => "0000000000000000000000000000000000000001",
36 Gy => "0000000000000000000000000000000000000002",
37 cofactor => 1,
38 oid => '2.23.43.1.4.9',
36139 },
36240 );
36341
364 my %jwkcrv = (
365 'P-192' => 'secp192r1',
366 'P-224' => 'secp224r1',
367 'P-256' => 'secp256r1',
368 'P-384' => 'secp384r1',
369 'P-521' => 'secp521r1',
42 my %jwk2curve = (
43 'P-192' => 'secp192r1',
44 'P-224' => 'secp224r1',
45 'P-256' => 'secp256r1',
46 'P-384' => 'secp384r1',
47 'P-521' => 'secp521r1',
48 );
49
50 my %curve2jwk = (
51 '1.2.840.10045.3.1.1' => 'P-192', # secp192r1
52 '1.3.132.0.33' => 'P-224', # secp224r1
53 '1.2.840.10045.3.1.7' => 'P-256', # secp256r1
54 '1.3.132.0.34' => 'P-384', # secp384r1
55 '1.3.132.0.35' => 'P-521', # secp521r1
56 'nistp192' => 'P-192',
57 'nistp224' => 'P-224',
58 'nistp256' => 'P-256',
59 'nistp384' => 'P-384',
60 'nistp521' => 'P-521',
61 'prime192v1' => 'P-192',
62 'prime256v1' => 'P-256',
63 'secp192r1' => 'P-192',
64 'secp224r1' => 'P-224',
65 'secp256r1' => 'P-256',
66 'secp384r1' => 'P-384',
67 'secp521r1' => 'P-521',
68 );
69
70 our %curve2ltc = ( # must be "our" as we use it from XS code
71 # OIDs
72 "1.2.840.10045.3.1.1" => "SECP192R1",
73 "1.2.840.10045.3.1.2" => "PRIME192V2",
74 "1.2.840.10045.3.1.3" => "PRIME192V3",
75 "1.2.840.10045.3.1.4" => "PRIME239V1",
76 "1.2.840.10045.3.1.5" => "PRIME239V2",
77 "1.2.840.10045.3.1.6" => "PRIME239V3",
78 "1.2.840.10045.3.1.7" => "SECP256R1",
79 "1.3.132.0.10" => "SECP256K1",
80 "1.3.132.0.28" => "SECP128R1",
81 "1.3.132.0.29" => "SECP128R2",
82 "1.3.132.0.30" => "SECP160R2",
83 "1.3.132.0.31" => "SECP192K1",
84 "1.3.132.0.32" => "SECP224K1",
85 "1.3.132.0.33" => "SECP224R1",
86 "1.3.132.0.34" => "SECP384R1",
87 "1.3.132.0.35" => "SECP521R1",
88 "1.3.132.0.6" => "SECP112R1",
89 "1.3.132.0.7" => "SECP112R2",
90 "1.3.132.0.8" => "SECP160R1",
91 "1.3.132.0.9" => "SECP160K1",
92 "1.3.36.3.3.2.8.1.1.1" => "BRAINPOOLP160R1",
93 "1.3.36.3.3.2.8.1.1.11" => "BRAINPOOLP384R1",
94 "1.3.36.3.3.2.8.1.1.13" => "BRAINPOOLP512R1",
95 "1.3.36.3.3.2.8.1.1.3" => "BRAINPOOLP192R1",
96 "1.3.36.3.3.2.8.1.1.5" => "BRAINPOOLP224R1",
97 "1.3.36.3.3.2.8.1.1.7" => "BRAINPOOLP256R1",
98 "1.3.36.3.3.2.8.1.1.9" => "BRAINPOOLP320R1",
99 "1.3.36.3.3.2.8.1.1.10" => "BRAINPOOLP320T1",
100 "1.3.36.3.3.2.8.1.1.12" => "BRAINPOOLP384T1",
101 "1.3.36.3.3.2.8.1.1.14" => "BRAINPOOLP512T1",
102 "1.3.36.3.3.2.8.1.1.2" => "BRAINPOOLP160T1",
103 "1.3.36.3.3.2.8.1.1.4" => "BRAINPOOLP192T1",
104 "1.3.36.3.3.2.8.1.1.6" => "BRAINPOOLP224T1",
105 "1.3.36.3.3.2.8.1.1.8" => "BRAINPOOLP256T1",
106 # JWT names
107 "P-192" => "SECP192R1",
108 "P-224" => "SECP224R1",
109 "P-256" => "SECP256R1",
110 "P-384" => "SECP384R1",
111 "P-521" => "SECP521R1",
112 # openssl names
113 "brainpoolp160r1" => "BRAINPOOLP160R1",
114 "brainpoolp192r1" => "BRAINPOOLP192R1",
115 "brainpoolp224r1" => "BRAINPOOLP224R1",
116 "brainpoolp256r1" => "BRAINPOOLP256R1",
117 "brainpoolp320r1" => "BRAINPOOLP320R1",
118 "brainpoolp384r1" => "BRAINPOOLP384R1",
119 "brainpoolp512r1" => "BRAINPOOLP512R1",
120 "brainpoolp160t1" => "BRAINPOOLP160T1",
121 "brainpoolp192t1" => "BRAINPOOLP192T1",
122 "brainpoolp224t1" => "BRAINPOOLP224T1",
123 "brainpoolp256t1" => "BRAINPOOLP256T1",
124 "brainpoolp320t1" => "BRAINPOOLP320T1",
125 "brainpoolp384t1" => "BRAINPOOLP384T1",
126 "brainpoolp512t1" => "BRAINPOOLP512T1",
127 "nistp192" => "SECP192R1",
128 "nistp224" => "SECP224R1",
129 "nistp256" => "SECP256R1",
130 "nistp384" => "SECP384R1",
131 "nistp521" => "SECP521R1",
132 "prime192v1" => "SECP192R1",
133 "prime192v2" => "PRIME192V2",
134 "prime192v3" => "PRIME192V3",
135 "prime239v1" => "PRIME239V1",
136 "prime239v2" => "PRIME239V2",
137 "prime239v3" => "PRIME239V3",
138 "prime256v1" => "SECP256R1",
139 "secp112r1" => "SECP112R1",
140 "secp112r2" => "SECP112R2",
141 "secp128r1" => "SECP128R1",
142 "secp128r2" => "SECP128R2",
143 "secp160k1" => "SECP160K1",
144 "secp160r1" => "SECP160R1",
145 "secp160r2" => "SECP160R2",
146 "secp192k1" => "SECP192K1",
147 "secp192r1" => "SECP192R1",
148 "secp224k1" => "SECP224K1",
149 "secp224r1" => "SECP224R1",
150 "secp256k1" => "SECP256K1",
151 "secp256r1" => "SECP256R1",
152 "secp384r1" => "SECP384R1",
153 "secp521r1" => "SECP521R1",
154 "wap-wsg-idm-ecid-wtls6" => 'SECP112R1',
155 "wap-wsg-idm-ecid-wtls7" => 'SECP160R2',
156 "wap-wsg-idm-ecid-wtls12" => 'SECP224R1',
370157 );
371158
372159 sub _import_hex {
373160 my ($self, $x, $y, $k, $crv) = @_;
374 my $p = $curve{$crv}{prime};
375 croak "FATAL: invalid or unknown curve" if !$p;
376 $p =~ s/^0+//;
377 my $hex_size = length($p) % 2 ? length($p) + 1 : length($p);
378 if ($k) {
379 $k =~ /^0+/;
380 croak "FATAL: too long private key (k)" if length($k) > $hex_size;
381 my $priv_hex = "0" x ($hex_size - length($k)) . $k;
382 return $self->import_key_raw(pack("H*", $priv_hex), $crv);
383 }
384 elsif ($x && $y) {
385 $x =~ /^0+/;
386 $y =~ /^0+/;
387 croak "FATAL: too long public key (x)" if length($x) > $hex_size;
388 croak "FATAL: too long public key (y)" if length($y) > $hex_size;
389 my $pub_hex = "04" . ("0" x ($hex_size - length($x))) . $x . ("0" x ($hex_size - length($y))) . $y;
161 croak "FATAL: no curve" if !$crv;
162 if (defined $k && length($k) > 0) {
163 croak "FATAL: invalid length (k)" if length($k) % 2;
164 return $self->import_key_raw(pack("H*", $k), $crv);
165 }
166 elsif (defined $x && defined $y) {
167 croak "FATAL: invalid length (x)" if length($x) % 2;
168 croak "FATAL: invalid length (y)" if length($y) % 2;
169 croak "FATAL: invalid length (x,y)" if length($y) != length($x);
170 my $pub_hex = "04" . $x . $y;
390171 return $self->import_key_raw(pack("H*", $pub_hex), $crv);
391 }
392 }
393
394 sub _curve_name_lookup {
395 my ($self, $key) = @_;
396
397 return $key->{curve_name} if $key->{curve_name} && exists $curve{$key->{curve_name}};
398
399 defined(my $A = $key->{curve_A}) or return;
400 defined(my $B = $key->{curve_B}) or return;
401 defined(my $Gx = $key->{curve_Gx}) or return;
402 defined(my $Gy = $key->{curve_Gy}) or return;
403 defined(my $order = $key->{curve_order}) or return;
404 defined(my $prime = $key->{curve_prime}) or return;
405 defined(my $cofactor = $key->{curve_cofactor}) or return;
406 $A =~ s/^0+//;
407 $B =~ s/^0+//;
408 $Gx =~ s/^0+//;
409 $Gy =~ s/^0+//;
410 $order =~ s/^0+//;
411 $prime =~ s/^0+//;
412
413 for my $k (sort keys %curve) {
414 (my $c_A = $curve{$k}{A} ) =~ s/^0+//;
415 (my $c_B = $curve{$k}{B} ) =~ s/^0+//;
416 (my $c_Gx = $curve{$k}{Gx} ) =~ s/^0+//;
417 (my $c_Gy = $curve{$k}{Gy} ) =~ s/^0+//;
418 (my $c_order = $curve{$k}{order} ) =~ s/^0+//;
419 (my $c_prime = $curve{$k}{prime} ) =~ s/^0+//;
420 my $c_cofactor = $curve{$k}{cofactor};
421 return $k if $A eq $c_A && $B eq $c_B && $Gx eq $c_Gx && $Gy eq $c_Gy &&
422 $order eq $c_order && $prime eq $c_prime && $cofactor == $c_cofactor;
423172 }
424173 }
425174
430179
431180 sub export_key_pem {
432181 my ($self, $type, $password, $cipher) = @_;
182 local $SIG{__DIE__} = \&CryptX::_croak;
433183 my $key = $self->export_key_der($type||'');
434184 return unless $key;
435185 return der_to_pem($key, "EC PRIVATE KEY", $password, $cipher) if substr($type, 0, 7) eq 'private';
438188
439189 sub export_key_jwk {
440190 my ($self, $type, $wanthash) = @_;
191 local $SIG{__DIE__} = \&CryptX::_croak;
441192 my $kh = $self->key2hash;
442 my $curve = $self->_curve_name_lookup($kh);
443 $curve = 'P-192' if $curve =~ /(secp192r1|nistp192|prime192v1)/;
444 $curve = 'P-224' if $curve =~ /(secp224r1|nistp224)/;
445 $curve = 'P-256' if $curve =~ /(secp256r1|nistp256|prime256v1)/;
446 $curve = 'P-384' if $curve =~ /(secp384r1|nistp384)/;
447 $curve = 'P-521' if $curve =~ /(secp521r1|nistp521)/;
193 $kh->{curve_oid} = '' if !defined $kh->{curve_oid};
194 $kh->{curve_name} = '' if !defined $kh->{curve_name};
195 my $curve_jwt = $curve2jwk{$kh->{curve_oid}} || $curve2jwk{lc $kh->{curve_name}} || $kh->{curve_name};
448196 if ($type && $type eq 'private') {
449197 return unless $kh->{pub_x} && $kh->{pub_y} && $kh->{k};
450198 for (qw/pub_x pub_y k/) {
453201 # NOTE: x + y are not necessary in privkey
454202 # but they are used in https://tools.ietf.org/html/rfc7517#appendix-A.2
455203 my $hash = {
456 kty => "EC", crv=>$curve,
204 kty => "EC", crv => $curve_jwt,
457205 x => encode_b64u(pack("H*", $kh->{pub_x})),
458206 y => encode_b64u(pack("H*", $kh->{pub_y})),
459207 d => encode_b64u(pack("H*", $kh->{k})),
466214 $kh->{$_} = "0$kh->{$_}" if length($kh->{$_}) % 2;
467215 }
468216 my $hash = {
469 kty => "EC", crv=>$curve,
217 kty => "EC", crv => $curve_jwt,
470218 x => encode_b64u(pack("H*", $kh->{pub_x})),
471219 y => encode_b64u(pack("H*", $kh->{pub_y})),
472220 };
476224
477225 sub export_key_jwk_thumbprint {
478226 my ($self, $hash_name) = @_;
227 local $SIG{__DIE__} = \&CryptX::_croak;
479228 $hash_name ||= 'SHA256';
480229 my $h = $self->export_key_jwk('public', 1);
481230 my $json = CryptX::_encode_json({crv=>$h->{crv}, kty=>$h->{kty}, x=>$h->{x}, y=>$h->{y}});
484233
485234 sub import_key {
486235 my ($self, $key, $password) = @_;
236 local $SIG{__DIE__} = \&CryptX::_croak;
487237 croak "FATAL: undefined key" unless $key;
488238
489239 # special case
490240 if (ref($key) eq 'HASH') {
491241 if (($key->{pub_x} && $key->{pub_y}) || $key->{k}) {
492242 # hash exported via key2hash
493 my $curve = $self->_curve_name_lookup($key);
494 croak "FATAL: invalid or unknown curve" if !$curve;
495 return $self->_import_hex($key->{pub_x}, $key->{pub_y}, $key->{k}, $curve);
243 my $curve_name = $key->{curve_name} || $key->{curve_oid};
244 return $self->_import_hex($key->{pub_x}, $key->{pub_y}, $key->{k}, $curve_name);
496245 }
497246 if ($key->{crv} && $key->{kty} && $key->{kty} eq "EC" && ($key->{d} || ($key->{x} && $key->{y}))) {
498247 # hash with items corresponding to JSON Web Key (JWK)
500249 for (qw/x y d/) {
501250 $key->{$_} = eval { unpack("H*", decode_b64u($key->{$_})) } if exists $key->{$_};
502251 }
503 if (my $curve = $jwkcrv{$key->{crv}}) {
504 return $self->_import_hex($key->{x}, $key->{y}, $key->{d}, $curve);
252 if (my $curve_name = $jwk2curve{$key->{crv}}) {
253 return $self->_import_hex($key->{x}, $key->{y}, $key->{d}, $curve_name);
505254 }
506255 # curve is not JWK compliant e.g. P-192 P-224 P-256 P-384 P-521 (we'll try to import anyway)
507 return $self->_import_hex($key->{x}, $key->{y}, $key->{d}, lc($key->{crv}));
256 return $self->_import_hex($key->{x}, $key->{y}, $key->{d}, $key->{crv});
508257 }
509258 croak "FATAL: unexpected ECC key hash";
510259 }
530279 return $self->_import_pkcs8($data, $password);
531280 }
532281 elsif ($data =~ /-----BEGIN ENCRYPTED PRIVATE KEY-----(.*?)-----END/sg) {
533 # XXX-TODO: pkcs#8 encrypted private key
534 croak "FATAL: encrypted pkcs8 EC private keys are not supported";
282 $data = pem_to_der($data, $password);
283 return $self->_import_pkcs8($data, $password);
535284 }
536285 elsif ($data =~ /^\s*(\{.*?\})\s*$/s) {
537286 # JSON Web Key (JWK) - http://tools.ietf.org/html/draft-ietf-jose-json-web-key
541290 for (qw/x y d/) {
542291 $h->{$_} = eval { unpack("H*", decode_b64u($h->{$_})) } if exists $h->{$_};
543292 }
544 if (my $curve = $jwkcrv{$h->{crv}}) {
545 return $self->_import_hex($h->{x}, $h->{y}, $h->{d}, $curve);
293 if (my $curve_name = $jwk2curve{$h->{crv}}) {
294 return $self->_import_hex($h->{x}, $h->{y}, $h->{d}, $curve_name);
546295 }
547296 # curve is not JWK compliant e.g. P-192 P-224 P-256 P-384 P-521 (we'll try to import anyway)
548 return $self->_import_hex($h->{x}, $h->{y}, $h->{d}, lc($h->{crv}));
297 return $self->_import_hex($h->{x}, $h->{y}, $h->{d}, $h->{crv});
549298 }
299 }
300 elsif ($data =~ /-----BEGIN CERTIFICATE-----(.*?)-----END CERTIFICATE-----/sg) {
301 $data = pem_to_der($data);
302 return $self->_import_x509($data);
550303 }
551304 elsif ($data =~ /---- BEGIN SSH2 PUBLIC KEY ----(.*?)---- END SSH2 PUBLIC KEY ----/sg) {
552305 $data = pem_to_der($data);
559312 return $self->import_key_raw($pubkey, "$2") if $pubkey && $typ =~ /^ecdsa-(.+?)-(.*)$/;
560313 }
561314 else {
562 my $rv = eval { $self->_import($data) } || eval { $self->_import_pkcs8($data, $password) };
315 my $rv = eval { $self->_import($data) } || eval { $self->_import_pkcs8($data, $password) } || eval { $self->_import_x509($data) };
563316 return $rv if $rv;
564317 }
565318 croak "FATAL: invalid or unsupported EC key format";
920673 lEHQYjWya2YnHaPq/iMFa7A=
921674 -----END PRIVATE KEY-----
922675
923 =item * PKCS#8 encrypted private keys ARE NOT SUPPORTED YET!
676 =item * PKCS#8 encrypted private keys
924677
925678 -----BEGIN ENCRYPTED PRIVATE KEY-----
926679 MIGYMBwGCiqGSIb3DQEMAQMwDgQINApjTa6oFl0CAggABHi+59l4d4e6KtG9yci2
928681 NfckdL5O2L8MRnM+ljkFtV2Te4fszWcJFdd7KiNOkPpn+7sWLfzQdvhHChLKUzmz
929682 4INKZyMv/G7VpZ0=
930683 -----END ENCRYPTED PRIVATE KEY-----
684
685 =item * EC public key from X509 certificate
686
687 -----BEGIN CERTIFICATE-----
688 MIIBdDCCARqgAwIBAgIJAL2BBClDEnnOMAoGCCqGSM49BAMEMBcxFTATBgNVBAMM
689 DFRlc3QgQ2VydCBFQzAgFw0xNzEyMzAyMDMzNDFaGA8zMDE3MDUwMjIwMzM0MVow
690 FzEVMBMGA1UEAwwMVGVzdCBDZXJ0IEVDMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE
691 KvkL2r5xZp7RzxLQJK+6tn/7lic+L70e1fmNbHOdxRaRvbK5G0AQWrdsbjJb92Ni
692 lCQk2+w/i+VuS2Q3MSR5TaNQME4wHQYDVR0OBBYEFGbJkDyKgaMcIGHS8/WuqIVw
693 +R8sMB8GA1UdIwQYMBaAFGbJkDyKgaMcIGHS8/WuqIVw+R8sMAwGA1UdEwQFMAMB
694 Af8wCgYIKoZIzj0EAwQDSAAwRQIhAJtOsmrM+gJpImoynAyqTN+7myL71uxd+YeC
695 6ze4MnzWAiBQi5/BqEr/SQ1+BC2TPtswvJPRFh2ZvT/6Km3gKoNVXQ==
696 -----END CERTIFICATE-----
931697
932698 =item * SSH public EC keys
933699
1003769 my $private_pem = $pk->export_key_pem('private_short');
1004770 #or
1005771 my $public_pem = $pk->export_key_pem('public_short');
772
773 Since CryptX-0.58 C<export_key_pem> can also export keys in "compressed" format
774 that defines curve by OID + stores public point in compressed form.
775
776 my $private_pem = $pk->export_key_pem('private_compressed');
777 #or
778 my $public_pem = $pk->export_key_pem('public_compressed');
1006779
1007780 Support for password protected PEM keys
1008781
1110883 my $pk = Crypt::PK::ECC->new($priv_key_filename);
1111884 my $signature = $priv->sign_hash($message_hash);
1112885
886 =head2 sign_hash_rfc7518
887
888 I<Since: CryptX-0.059>
889
890 Same as L<sign_hash|/sign_hash> only the signature format is as defined by L<https://tools.ietf.org/html/rfc7518>
891 (JWA - JSON Web Algorithms).
892
1113893 =head2 verify_hash
1114894
1115895 my $pk = Crypt::PK::ECC->new($pub_key_filename);
1116896 my $valid = $pub->verify_hash($signature, $message_hash);
897
898 =head2 verify_hash_rfc7518
899
900 I<Since: CryptX-0.059>
901
902 Same as L<verify_hash|/verify_hash> only the signature format is as defined by L<https://tools.ietf.org/html/rfc7518>
903 (JWA - JSON Web Algorithms).
1117904
1118905 =head2 shared_secret
1119906
6565 ltc/pk/asn1/der/bit/der_encode_bit_string.o ltc/pk/asn1/der/bit/der_encode_raw_bit_string.o \
6666 ltc/pk/asn1/der/bit/der_length_bit_string.o ltc/pk/asn1/der/boolean/der_decode_boolean.o \
6767 ltc/pk/asn1/der/boolean/der_encode_boolean.o ltc/pk/asn1/der/boolean/der_length_boolean.o \
68 ltc/pk/asn1/der/choice/der_decode_choice.o ltc/pk/asn1/der/generalizedtime/der_decode_generalizedtime.o \
68 ltc/pk/asn1/der/choice/der_decode_choice.o ltc/pk/asn1/der/custom_type/der_decode_custom_type.o \
69 ltc/pk/asn1/der/custom_type/der_encode_custom_type.o ltc/pk/asn1/der/custom_type/der_length_custom_type.o \
70 ltc/pk/asn1/der/general/der_asn1_maps.o ltc/pk/asn1/der/general/der_decode_asn1_identifier.o \
71 ltc/pk/asn1/der/general/der_decode_asn1_length.o ltc/pk/asn1/der/general/der_encode_asn1_identifier.o \
72 ltc/pk/asn1/der/general/der_encode_asn1_length.o ltc/pk/asn1/der/general/der_length_asn1_identifier.o \
73 ltc/pk/asn1/der/general/der_length_asn1_length.o ltc/pk/asn1/der/generalizedtime/der_decode_generalizedtime.o \
6974 ltc/pk/asn1/der/generalizedtime/der_encode_generalizedtime.o ltc/pk/asn1/der/generalizedtime/der_length_generalizedtime.o \
7075 ltc/pk/asn1/der/ia5/der_decode_ia5_string.o ltc/pk/asn1/der/ia5/der_encode_ia5_string.o \
7176 ltc/pk/asn1/der/ia5/der_length_ia5_string.o ltc/pk/asn1/der/integer/der_decode_integer.o \
7681 ltc/pk/asn1/der/printable_string/der_decode_printable_string.o ltc/pk/asn1/der/printable_string/der_encode_printable_string.o \
7782 ltc/pk/asn1/der/printable_string/der_length_printable_string.o ltc/pk/asn1/der/sequence/der_decode_sequence_ex.o \
7883 ltc/pk/asn1/der/sequence/der_decode_sequence_flexi.o ltc/pk/asn1/der/sequence/der_decode_sequence_multi.o \
79 ltc/pk/asn1/der/sequence/der_decode_subject_public_key_info.o ltc/pk/asn1/der/sequence/der_encode_sequence_ex.o \
80 ltc/pk/asn1/der/sequence/der_encode_sequence_multi.o ltc/pk/asn1/der/sequence/der_encode_subject_public_key_info.o \
84 ltc/pk/asn1/der/sequence/der_encode_sequence_ex.o ltc/pk/asn1/der/sequence/der_encode_sequence_multi.o \
8185 ltc/pk/asn1/der/sequence/der_length_sequence.o ltc/pk/asn1/der/sequence/der_sequence_free.o \
8286 ltc/pk/asn1/der/sequence/der_sequence_shrink.o ltc/pk/asn1/der/set/der_encode_set.o \
8387 ltc/pk/asn1/der/set/der_encode_setof.o ltc/pk/asn1/der/short_integer/der_decode_short_integer.o \
8690 ltc/pk/asn1/der/utctime/der_decode_utctime.o ltc/pk/asn1/der/utctime/der_encode_utctime.o \
8791 ltc/pk/asn1/der/utctime/der_length_utctime.o ltc/pk/asn1/der/utf8/der_decode_utf8_string.o \
8892 ltc/pk/asn1/der/utf8/der_encode_utf8_string.o ltc/pk/asn1/der/utf8/der_length_utf8_string.o \
93 ltc/pk/asn1/x509/x509_decode_subject_public_key_info.o ltc/pk/asn1/x509/x509_encode_subject_public_key_info.o \
8994 ltc/pk/dh/dh.o ltc/pk/dh/dh_check_pubkey.o ltc/pk/dh/dh_export.o ltc/pk/dh/dh_export_key.o \
9095 ltc/pk/dh/dh_free.o ltc/pk/dh/dh_generate_key.o ltc/pk/dh/dh_import.o ltc/pk/dh/dh_set.o \
9196 ltc/pk/dh/dh_set_pg_dhparam.o ltc/pk/dh/dh_shared_secret.o ltc/pk/dsa/dsa_decrypt_key.o \
9398 ltc/pk/dsa/dsa_generate_pqg.o ltc/pk/dsa/dsa_import.o ltc/pk/dsa/dsa_make_key.o ltc/pk/dsa/dsa_set.o \
9499 ltc/pk/dsa/dsa_set_pqg_dsaparam.o ltc/pk/dsa/dsa_shared_secret.o ltc/pk/dsa/dsa_sign_hash.o \
95100 ltc/pk/dsa/dsa_verify_hash.o ltc/pk/dsa/dsa_verify_key.o ltc/pk/ecc/ecc.o ltc/pk/ecc/ecc_ansi_x963_export.o \
96 ltc/pk/ecc/ecc_ansi_x963_import.o ltc/pk/ecc/ecc_decrypt_key.o ltc/pk/ecc/ecc_dp_clear.o \
97 ltc/pk/ecc/ecc_dp_fill_from_sets.o ltc/pk/ecc/ecc_dp_from_oid.o ltc/pk/ecc/ecc_dp_from_params.o \
98 ltc/pk/ecc/ecc_dp_init.o ltc/pk/ecc/ecc_dp_set.o ltc/pk/ecc/ecc_encrypt_key.o ltc/pk/ecc/ecc_export.o \
99 ltc/pk/ecc/ecc_export_full.o ltc/pk/ecc/ecc_export_raw.o ltc/pk/ecc/ecc_free.o ltc/pk/ecc/ecc_get_size.o \
100 ltc/pk/ecc/ecc_import.o ltc/pk/ecc/ecc_import_full.o ltc/pk/ecc/ecc_import_pkcs8.o \
101 ltc/pk/ecc/ecc_import_raw.o ltc/pk/ecc/ecc_make_key.o ltc/pk/ecc/ecc_shared_secret.o \
102 ltc/pk/ecc/ecc_sign_hash.o ltc/pk/ecc/ecc_sizes.o ltc/pk/ecc/ecc_verify_hash.o ltc/pk/ecc/ecc_verify_key.o \
103 ltc/pk/ecc/ltc_ecc_export_point.o ltc/pk/ecc/ltc_ecc_import_point.o ltc/pk/ecc/ltc_ecc_is_point.o \
104 ltc/pk/ecc/ltc_ecc_is_point_at_infinity.o ltc/pk/ecc/ltc_ecc_is_valid_idx.o ltc/pk/ecc/ltc_ecc_map.o \
101 ltc/pk/ecc/ecc_ansi_x963_import.o ltc/pk/ecc/ecc_decrypt_key.o ltc/pk/ecc/ecc_encrypt_key.o \
102 ltc/pk/ecc/ecc_export.o ltc/pk/ecc/ecc_export_openssl.o ltc/pk/ecc/ecc_free.o ltc/pk/ecc/ecc_get_key.o \
103 ltc/pk/ecc/ecc_get_set.o ltc/pk/ecc/ecc_get_size.o ltc/pk/ecc/ecc_import.o ltc/pk/ecc/ecc_import_openssl.o \
104 ltc/pk/ecc/ecc_import_pkcs8.o ltc/pk/ecc/ecc_import_x509.o ltc/pk/ecc/ecc_make_key.o \
105 ltc/pk/ecc/ecc_set_dp.o ltc/pk/ecc/ecc_set_dp_internal.o ltc/pk/ecc/ecc_set_key.o \
106 ltc/pk/ecc/ecc_shared_secret.o ltc/pk/ecc/ecc_sign_hash.o ltc/pk/ecc/ecc_sizes.o \
107 ltc/pk/ecc/ecc_verify_hash.o ltc/pk/ecc/ltc_ecc_export_point.o ltc/pk/ecc/ltc_ecc_import_point.o \
108 ltc/pk/ecc/ltc_ecc_is_point.o ltc/pk/ecc/ltc_ecc_is_point_at_infinity.o ltc/pk/ecc/ltc_ecc_map.o \
105109 ltc/pk/ecc/ltc_ecc_mul2add.o ltc/pk/ecc/ltc_ecc_mulmod.o ltc/pk/ecc/ltc_ecc_mulmod_timing.o \
106110 ltc/pk/ecc/ltc_ecc_points.o ltc/pk/ecc/ltc_ecc_projective_add_point.o ltc/pk/ecc/ltc_ecc_projective_dbl_point.o \
107 ltc/pk/pkcs1/pkcs_1_i2osp.o ltc/pk/pkcs1/pkcs_1_mgf1.o ltc/pk/pkcs1/pkcs_1_oaep_decode.o \
108 ltc/pk/pkcs1/pkcs_1_oaep_encode.o ltc/pk/pkcs1/pkcs_1_os2ip.o ltc/pk/pkcs1/pkcs_1_pss_decode.o \
109 ltc/pk/pkcs1/pkcs_1_pss_encode.o ltc/pk/pkcs1/pkcs_1_v1_5_decode.o ltc/pk/pkcs1/pkcs_1_v1_5_encode.o \
110 ltc/pk/rsa/rsa_decrypt_key.o ltc/pk/rsa/rsa_encrypt_key.o ltc/pk/rsa/rsa_export.o \
111 ltc/pk/rsa/rsa_exptmod.o ltc/pk/rsa/rsa_free.o ltc/pk/rsa/rsa_get_size.o ltc/pk/rsa/rsa_import.o \
112 ltc/pk/rsa/rsa_import_pkcs8.o ltc/pk/rsa/rsa_import_x509.o ltc/pk/rsa/rsa_make_key.o \
113 ltc/pk/rsa/rsa_set.o ltc/pk/rsa/rsa_sign_hash.o ltc/pk/rsa/rsa_sign_saltlen_get.o \
111 ltc/pk/ecc/ltc_ecc_verify_key.o ltc/pk/pkcs1/pkcs_1_i2osp.o ltc/pk/pkcs1/pkcs_1_mgf1.o \
112 ltc/pk/pkcs1/pkcs_1_oaep_decode.o ltc/pk/pkcs1/pkcs_1_oaep_encode.o ltc/pk/pkcs1/pkcs_1_os2ip.o \
113 ltc/pk/pkcs1/pkcs_1_pss_decode.o ltc/pk/pkcs1/pkcs_1_pss_encode.o ltc/pk/pkcs1/pkcs_1_v1_5_decode.o \
114 ltc/pk/pkcs1/pkcs_1_v1_5_encode.o ltc/pk/rsa/rsa_decrypt_key.o ltc/pk/rsa/rsa_encrypt_key.o \
115 ltc/pk/rsa/rsa_export.o ltc/pk/rsa/rsa_exptmod.o ltc/pk/rsa/rsa_free.o ltc/pk/rsa/rsa_get_size.o \
116 ltc/pk/rsa/rsa_import.o ltc/pk/rsa/rsa_import_pkcs8.o ltc/pk/rsa/rsa_import_x509.o \
117 ltc/pk/rsa/rsa_make_key.o ltc/pk/rsa/rsa_set.o ltc/pk/rsa/rsa_sign_hash.o ltc/pk/rsa/rsa_sign_saltlen_get.o \
114118 ltc/pk/rsa/rsa_verify_hash.o ltc/prngs/chacha20.o ltc/prngs/fortuna.o ltc/prngs/rc4.o \
115119 ltc/prngs/rng_get_bytes.o ltc/prngs/rng_make_prng.o ltc/prngs/sober128.o ltc/prngs/sprng.o \
116120 ltc/prngs/yarrow.o ltc/stream/chacha/chacha_crypt.o ltc/stream/chacha/chacha_done.o \
7272 ltc/pk/asn1/der/bit/der_encode_raw_bit_string.obj ltc/pk/asn1/der/bit/der_length_bit_string.obj \
7373 ltc/pk/asn1/der/boolean/der_decode_boolean.obj ltc/pk/asn1/der/boolean/der_encode_boolean.obj \
7474 ltc/pk/asn1/der/boolean/der_length_boolean.obj ltc/pk/asn1/der/choice/der_decode_choice.obj \
75 ltc/pk/asn1/der/custom_type/der_decode_custom_type.obj ltc/pk/asn1/der/custom_type/der_encode_custom_type.obj \
76 ltc/pk/asn1/der/custom_type/der_length_custom_type.obj ltc/pk/asn1/der/general/der_asn1_maps.obj \
77 ltc/pk/asn1/der/general/der_decode_asn1_identifier.obj ltc/pk/asn1/der/general/der_decode_asn1_length.obj \
78 ltc/pk/asn1/der/general/der_encode_asn1_identifier.obj ltc/pk/asn1/der/general/der_encode_asn1_length.obj \
79 ltc/pk/asn1/der/general/der_length_asn1_identifier.obj ltc/pk/asn1/der/general/der_length_asn1_length.obj \
7580 ltc/pk/asn1/der/generalizedtime/der_decode_generalizedtime.obj ltc/pk/asn1/der/generalizedtime/der_encode_generalizedtime.obj \
7681 ltc/pk/asn1/der/generalizedtime/der_length_generalizedtime.obj ltc/pk/asn1/der/ia5/der_decode_ia5_string.obj \
7782 ltc/pk/asn1/der/ia5/der_encode_ia5_string.obj ltc/pk/asn1/der/ia5/der_length_ia5_string.obj \
8287 ltc/pk/asn1/der/octet/der_length_octet_string.obj ltc/pk/asn1/der/printable_string/der_decode_printable_string.obj \
8388 ltc/pk/asn1/der/printable_string/der_encode_printable_string.obj ltc/pk/asn1/der/printable_string/der_length_printable_string.obj \
8489 ltc/pk/asn1/der/sequence/der_decode_sequence_ex.obj ltc/pk/asn1/der/sequence/der_decode_sequence_flexi.obj \
85 ltc/pk/asn1/der/sequence/der_decode_sequence_multi.obj ltc/pk/asn1/der/sequence/der_decode_subject_public_key_info.obj \
86 ltc/pk/asn1/der/sequence/der_encode_sequence_ex.obj ltc/pk/asn1/der/sequence/der_encode_sequence_multi.obj \
87 ltc/pk/asn1/der/sequence/der_encode_subject_public_key_info.obj ltc/pk/asn1/der/sequence/der_length_sequence.obj \
90 ltc/pk/asn1/der/sequence/der_decode_sequence_multi.obj ltc/pk/asn1/der/sequence/der_encode_sequence_ex.obj \
91 ltc/pk/asn1/der/sequence/der_encode_sequence_multi.obj ltc/pk/asn1/der/sequence/der_length_sequence.obj \
8892 ltc/pk/asn1/der/sequence/der_sequence_free.obj ltc/pk/asn1/der/sequence/der_sequence_shrink.obj \
8993 ltc/pk/asn1/der/set/der_encode_set.obj ltc/pk/asn1/der/set/der_encode_setof.obj ltc/pk/asn1/der/short_integer/der_decode_short_integer.obj \
9094 ltc/pk/asn1/der/short_integer/der_encode_short_integer.obj ltc/pk/asn1/der/short_integer/der_length_short_integer.obj \
9296 ltc/pk/asn1/der/utctime/der_decode_utctime.obj ltc/pk/asn1/der/utctime/der_encode_utctime.obj \
9397 ltc/pk/asn1/der/utctime/der_length_utctime.obj ltc/pk/asn1/der/utf8/der_decode_utf8_string.obj \
9498 ltc/pk/asn1/der/utf8/der_encode_utf8_string.obj ltc/pk/asn1/der/utf8/der_length_utf8_string.obj \
99 ltc/pk/asn1/x509/x509_decode_subject_public_key_info.obj ltc/pk/asn1/x509/x509_encode_subject_public_key_info.obj \
95100 ltc/pk/dh/dh.obj ltc/pk/dh/dh_check_pubkey.obj ltc/pk/dh/dh_export.obj ltc/pk/dh/dh_export_key.obj \
96101 ltc/pk/dh/dh_free.obj ltc/pk/dh/dh_generate_key.obj ltc/pk/dh/dh_import.obj ltc/pk/dh/dh_set.obj \
97102 ltc/pk/dh/dh_set_pg_dhparam.obj ltc/pk/dh/dh_shared_secret.obj ltc/pk/dsa/dsa_decrypt_key.obj \
100105 ltc/pk/dsa/dsa_make_key.obj ltc/pk/dsa/dsa_set.obj ltc/pk/dsa/dsa_set_pqg_dsaparam.obj \
101106 ltc/pk/dsa/dsa_shared_secret.obj ltc/pk/dsa/dsa_sign_hash.obj ltc/pk/dsa/dsa_verify_hash.obj \
102107 ltc/pk/dsa/dsa_verify_key.obj ltc/pk/ecc/ecc.obj ltc/pk/ecc/ecc_ansi_x963_export.obj \
103 ltc/pk/ecc/ecc_ansi_x963_import.obj ltc/pk/ecc/ecc_decrypt_key.obj ltc/pk/ecc/ecc_dp_clear.obj \
104 ltc/pk/ecc/ecc_dp_fill_from_sets.obj ltc/pk/ecc/ecc_dp_from_oid.obj ltc/pk/ecc/ecc_dp_from_params.obj \
105 ltc/pk/ecc/ecc_dp_init.obj ltc/pk/ecc/ecc_dp_set.obj ltc/pk/ecc/ecc_encrypt_key.obj \
106 ltc/pk/ecc/ecc_export.obj ltc/pk/ecc/ecc_export_full.obj ltc/pk/ecc/ecc_export_raw.obj \
107 ltc/pk/ecc/ecc_free.obj ltc/pk/ecc/ecc_get_size.obj ltc/pk/ecc/ecc_import.obj ltc/pk/ecc/ecc_import_full.obj \
108 ltc/pk/ecc/ecc_import_pkcs8.obj ltc/pk/ecc/ecc_import_raw.obj ltc/pk/ecc/ecc_make_key.obj \
109 ltc/pk/ecc/ecc_shared_secret.obj ltc/pk/ecc/ecc_sign_hash.obj ltc/pk/ecc/ecc_sizes.obj \
110 ltc/pk/ecc/ecc_verify_hash.obj ltc/pk/ecc/ecc_verify_key.obj ltc/pk/ecc/ltc_ecc_export_point.obj \
111 ltc/pk/ecc/ltc_ecc_import_point.obj ltc/pk/ecc/ltc_ecc_is_point.obj ltc/pk/ecc/ltc_ecc_is_point_at_infinity.obj \
112 ltc/pk/ecc/ltc_ecc_is_valid_idx.obj ltc/pk/ecc/ltc_ecc_map.obj ltc/pk/ecc/ltc_ecc_mul2add.obj \
108 ltc/pk/ecc/ecc_ansi_x963_import.obj ltc/pk/ecc/ecc_decrypt_key.obj ltc/pk/ecc/ecc_encrypt_key.obj \
109 ltc/pk/ecc/ecc_export.obj ltc/pk/ecc/ecc_export_openssl.obj ltc/pk/ecc/ecc_free.obj \
110 ltc/pk/ecc/ecc_get_key.obj ltc/pk/ecc/ecc_get_set.obj ltc/pk/ecc/ecc_get_size.obj \
111 ltc/pk/ecc/ecc_import.obj ltc/pk/ecc/ecc_import_openssl.obj ltc/pk/ecc/ecc_import_pkcs8.obj \
112 ltc/pk/ecc/ecc_import_x509.obj ltc/pk/ecc/ecc_make_key.obj ltc/pk/ecc/ecc_set_dp.obj \
113 ltc/pk/ecc/ecc_set_dp_internal.obj ltc/pk/ecc/ecc_set_key.obj ltc/pk/ecc/ecc_shared_secret.obj \
114 ltc/pk/ecc/ecc_sign_hash.obj ltc/pk/ecc/ecc_sizes.obj ltc/pk/ecc/ecc_verify_hash.obj \
115 ltc/pk/ecc/ltc_ecc_export_point.obj ltc/pk/ecc/ltc_ecc_import_point.obj ltc/pk/ecc/ltc_ecc_is_point.obj \
116 ltc/pk/ecc/ltc_ecc_is_point_at_infinity.obj ltc/pk/ecc/ltc_ecc_map.obj ltc/pk/ecc/ltc_ecc_mul2add.obj \
113117 ltc/pk/ecc/ltc_ecc_mulmod.obj ltc/pk/ecc/ltc_ecc_mulmod_timing.obj ltc/pk/ecc/ltc_ecc_points.obj \
114118 ltc/pk/ecc/ltc_ecc_projective_add_point.obj ltc/pk/ecc/ltc_ecc_projective_dbl_point.obj \
115 ltc/pk/pkcs1/pkcs_1_i2osp.obj ltc/pk/pkcs1/pkcs_1_mgf1.obj ltc/pk/pkcs1/pkcs_1_oaep_decode.obj \
116 ltc/pk/pkcs1/pkcs_1_oaep_encode.obj ltc/pk/pkcs1/pkcs_1_os2ip.obj ltc/pk/pkcs1/pkcs_1_pss_decode.obj \
117 ltc/pk/pkcs1/pkcs_1_pss_encode.obj ltc/pk/pkcs1/pkcs_1_v1_5_decode.obj ltc/pk/pkcs1/pkcs_1_v1_5_encode.obj \
118 ltc/pk/rsa/rsa_decrypt_key.obj ltc/pk/rsa/rsa_encrypt_key.obj ltc/pk/rsa/rsa_export.obj \
119 ltc/pk/rsa/rsa_exptmod.obj ltc/pk/rsa/rsa_free.obj ltc/pk/rsa/rsa_get_size.obj ltc/pk/rsa/rsa_import.obj \
120 ltc/pk/rsa/rsa_import_pkcs8.obj ltc/pk/rsa/rsa_import_x509.obj ltc/pk/rsa/rsa_make_key.obj \
121 ltc/pk/rsa/rsa_set.obj ltc/pk/rsa/rsa_sign_hash.obj ltc/pk/rsa/rsa_sign_saltlen_get.obj \
119 ltc/pk/ecc/ltc_ecc_verify_key.obj ltc/pk/pkcs1/pkcs_1_i2osp.obj ltc/pk/pkcs1/pkcs_1_mgf1.obj \
120 ltc/pk/pkcs1/pkcs_1_oaep_decode.obj ltc/pk/pkcs1/pkcs_1_oaep_encode.obj ltc/pk/pkcs1/pkcs_1_os2ip.obj \
121 ltc/pk/pkcs1/pkcs_1_pss_decode.obj ltc/pk/pkcs1/pkcs_1_pss_encode.obj ltc/pk/pkcs1/pkcs_1_v1_5_decode.obj \
122 ltc/pk/pkcs1/pkcs_1_v1_5_encode.obj ltc/pk/rsa/rsa_decrypt_key.obj ltc/pk/rsa/rsa_encrypt_key.obj \
123 ltc/pk/rsa/rsa_export.obj ltc/pk/rsa/rsa_exptmod.obj ltc/pk/rsa/rsa_free.obj ltc/pk/rsa/rsa_get_size.obj \
124 ltc/pk/rsa/rsa_import.obj ltc/pk/rsa/rsa_import_pkcs8.obj ltc/pk/rsa/rsa_import_x509.obj \
125 ltc/pk/rsa/rsa_make_key.obj ltc/pk/rsa/rsa_set.obj ltc/pk/rsa/rsa_sign_hash.obj ltc/pk/rsa/rsa_sign_saltlen_get.obj \
122126 ltc/pk/rsa/rsa_verify_hash.obj ltc/prngs/chacha20.obj ltc/prngs/fortuna.obj ltc/prngs/rc4.obj \
123127 ltc/prngs/rng_get_bytes.obj ltc/prngs/rng_make_prng.obj ltc/prngs/sober128.obj ltc/prngs/sprng.obj \
124128 ltc/prngs/yarrow.obj ltc/stream/chacha/chacha_crypt.obj ltc/stream/chacha/chacha_done.obj \
2626
2727 /* version */
2828 #define CRYPT 0x0118
29 #define SCRYPT "1.18.0"
29 #define SCRYPT "1.18.1-develop"
3030
3131 /* max size of either a cipher/hash block or symmetric key [largest of the two] */
3232 #define MAXBLOCKSIZE 144
6666
6767 CRYPT_OVERFLOW, /* An overflow of a value was detected/prevented */
6868
69 CRYPT_UNUSED1, /* UNUSED1 */
69 CRYPT_PK_ASN1_ERROR, /* An error occurred while en- or decoding ASN.1 data */
7070
7171 CRYPT_INPUT_TOO_LONG, /* The input was longer than expected. */
7272
467467 #ifdef LTC_MECC
468468 /* Supported ECC Key Sizes */
469469 #ifndef LTC_NO_CURVES
470 #define LTC_ECC_BRAINPOOLP160R1
471 #define LTC_ECC_BRAINPOOLP160T1
472 #define LTC_ECC_BRAINPOOLP192R1
473 #define LTC_ECC_BRAINPOOLP192T1
474 #define LTC_ECC_BRAINPOOLP224R1
475 #define LTC_ECC_BRAINPOOLP224T1
476 #define LTC_ECC_BRAINPOOLP256R1
477 #define LTC_ECC_BRAINPOOLP256T1
478 #define LTC_ECC_BRAINPOOLP320R1
479 #define LTC_ECC_BRAINPOOLP320T1
480 #define LTC_ECC_BRAINPOOLP384R1
481 #define LTC_ECC_BRAINPOOLP384T1
482 #define LTC_ECC_BRAINPOOLP512R1
483 #define LTC_ECC_BRAINPOOLP512T1
484 #define LTC_ECC_PRIME192V2
485 #define LTC_ECC_PRIME192V3
486 #define LTC_ECC_PRIME239V1
487 #define LTC_ECC_PRIME239V2
488 #define LTC_ECC_PRIME239V3
470489 #define LTC_ECC_SECP112R1
471490 #define LTC_ECC_SECP112R2
472491 #define LTC_ECC_SECP128R1
473492 #define LTC_ECC_SECP128R2
493 #define LTC_ECC_SECP160K1
474494 #define LTC_ECC_SECP160R1
475495 #define LTC_ECC_SECP160R2
476 #define LTC_ECC_SECP160K1
477 #define LTC_ECC_BRAINPOOLP160R1
496 #define LTC_ECC_SECP192K1
478497 #define LTC_ECC_SECP192R1
479 #define LTC_ECC_PRIME192V2
480 #define LTC_ECC_PRIME192V3
481 #define LTC_ECC_SECP192K1
482 #define LTC_ECC_BRAINPOOLP192R1
498 #define LTC_ECC_SECP224K1
483499 #define LTC_ECC_SECP224R1
484 #define LTC_ECC_SECP224K1
485 #define LTC_ECC_BRAINPOOLP224R1
486 #define LTC_ECC_PRIME239V1
487 #define LTC_ECC_PRIME239V2
488 #define LTC_ECC_PRIME239V3
500 #define LTC_ECC_SECP256K1
489501 #define LTC_ECC_SECP256R1
490 #define LTC_ECC_SECP256K1
491 #define LTC_ECC_BRAINPOOLP256R1
492 #define LTC_ECC_BRAINPOOLP320R1
493502 #define LTC_ECC_SECP384R1
494 #define LTC_ECC_BRAINPOOLP384R1
495 #define LTC_ECC_BRAINPOOLP512R1
496503 #define LTC_ECC_SECP521R1
497504 /* OLD deprecated (but still working) defines */
498505 #define LTC_ECC112
373373 @param k The integer to multiply the point by
374374 @param G The point to multiply
375375 @param R The destination for kG
376 @param a ECC curve parameter a (if NULL we assume a == -3)
376 @param a ECC curve parameter a
377377 @param modulus The modulus for the field
378378 @param map Boolean indicated whether to map back to affine or not
379379 (can be ignored if you work in affine only)
380380 @return CRYPT_OK on success
381381 */
382382 int (*ecc_ptmul)( void *k,
383 ecc_point *G,
384 ecc_point *R,
385 void *a,
386 void *modulus,
387 int map);
383 const ecc_point *G,
384 ecc_point *R,
385 void *a,
386 void *modulus,
387 int map);
388388
389389 /** ECC GF(p) point addition
390390 @param P The first point
391391 @param Q The second point
392392 @param R The destination of P + Q
393 @param a ECC curve parameter a (if NULL we assume a == -3)
393 @param ma The curve parameter "a" in montgomery form
394394 @param modulus The modulus
395395 @param mp The "b" value from montgomery_setup()
396396 @return CRYPT_OK on success
397397 */
398 int (*ecc_ptadd)(ecc_point *P,
399 ecc_point *Q,
400 ecc_point *R,
401 void *a,
402 void *modulus,
403 void *mp);
398 int (*ecc_ptadd)(const ecc_point *P,
399 const ecc_point *Q,
400 ecc_point *R,
401 void *ma,
402 void *modulus,
403 void *mp);
404404
405405 /** ECC GF(p) point double
406406 @param P The first point
407407 @param R The destination of 2P
408 @param a ECC curve parameter a (if NULL we assume a == -3)
408 @param ma The curve parameter "a" in montgomery form
409409 @param modulus The modulus
410410 @param mp The "b" value from montgomery_setup()
411411 @return CRYPT_OK on success
412412 */
413 int (*ecc_ptdbl)(ecc_point *P,
414 ecc_point *R,
415 void *a,
416 void *modulus,
417 void *mp);
413 int (*ecc_ptdbl)(const ecc_point *P,
414 ecc_point *R,
415 void *ma,
416 void *modulus,
417 void *mp);
418418
419419 /** ECC mapping from projective to affine,
420420 currently uses (x,y,z) => (x/z^2, y/z^3, 1)
434434 @param B Second point to multiply
435435 @param kB What to multiple B by
436436 @param C [out] Destination point (can overlap with A or B)
437 @param ma The curve parameter "a" in montgomery form
437438 @param modulus Modulus for curve
438439 @return CRYPT_OK on success
439440 */
440 int (*ecc_mul2add)(ecc_point *A, void *kA,
441 ecc_point *B, void *kB,
442 ecc_point *C,
443 void *a,
444 void *modulus);
441 int (*ecc_mul2add)(const ecc_point *A, void *kA,
442 const ecc_point *B, void *kB,
443 ecc_point *C,
444 void *ma,
445 void *modulus);
445446
446447 /* ---- (optional) rsa optimized math (for internal CRT) ---- */
447448
3131 PKA_RSA,
3232 PKA_DSA,
3333 PKA_EC,
34 EC_PRIME_FIELD
34 PKA_EC_PRIMEF
3535 };
36 #endif /* LTC_SOURCE */
3736
3837 typedef struct Oid {
3938 unsigned long OID[16];
40 /** Length of DER encoding */
39 /** Number of OID digits in use */
4140 unsigned long OIDlen;
4241 } oid_st;
4342
4443 int pk_get_oid(int pk, oid_st *st);
44 #endif /* LTC_SOURCE */
4545
4646 /* ---- RSA ---- */
4747 #ifdef LTC_MRSA
253253 /* max private key size */
254254 #define ECC_MAXSIZE 66
255255
256 /** Structure defines a NIST GF(p) curve */
256 /** Structure defines a GF(p) curve */
257257 typedef struct {
258 /** The size of the curve in octets */
259 int size;
260
261258 /** name of curve */
262 char *name;
259 const char *name;
263260
264261 /** The prime that defines the field the curve is in (encoded in hex) */
265 char *prime;
262 const char *prime;
266263
267264 /** The fields A param (hex) */
268 char *A;
265 const char *A;
269266
270267 /** The fields B param (hex) */
271 char *B;
268 const char *B;
272269
273270 /** The order of the curve (hex) */
274 char *order;
271 const char *order;
275272
276273 /** The x co-ordinate of the base point on the curve (hex) */
277 char *Gx;
274 const char *Gx;
278275
279276 /** The y co-ordinate of the base point on the curve (hex) */
280 char *Gy;
277 const char *Gy;
281278
282279 /** The co-factor */
283280 unsigned long cofactor;
284281
285 /** The OID stucture */
286 oid_st oid;
282 /** The OID */
283 unsigned long oid[16];
284 unsigned long oidlen;
287285 } ltc_ecc_set_type;
288286
289287 /** A point on a ECC curve, stored in Jacbobian format such that (x,y,z) => (x/z^2, y/z^3, 1) when interpretted as affine */
298296 void *z;
299297 } ecc_point;
300298
299 /** ECC key's domain parameters */
300 typedef struct {
301 /** The size of the curve in octets */
302 int size;
303 /** The prime that defines the field the curve is in */
304 void *prime;
305 /** The fields A param */
306 void *A;
307 /** The fields B param */
308 void *B;
309 /** The order of the curve */
310 void *order;
311 /** The base point G on the curve */
312 ecc_point base;
313 /** The co-factor */
314 unsigned long cofactor;
315 /** The OID */
316 unsigned long oid[16];
317 unsigned long oidlen;
318 } ltc_ecc_dp;
319
301320 /** An ECC key */
302321 typedef struct {
303322 /** Type of key, PK_PRIVATE or PK_PUBLIC */
304323 int type;
305324
306 /** Index into the ltc_ecc_sets[] for the parameters of this curve; if -1, then this key is using user supplied curve in dp */
307 int idx;
308
309 /** pointer to domain parameters; either points to NIST curves (identified by idx >= 0) or user supplied curve */
310 const ltc_ecc_set_type *dp;
311
312 /** The public key */
325 /** Structure with domain parameters */
326 ltc_ecc_dp dp;
327
328 /** Structure with the public key */
313329 ecc_point pubkey;
314330
315331 /** The private key */
323339 void ecc_sizes(int *low, int *high);
324340 int ecc_get_size(ecc_key *key);
325341
326 int ecc_dp_init(ltc_ecc_set_type *dp);
327 int ecc_dp_set(ltc_ecc_set_type *dp, char *ch_prime, char *ch_A, char *ch_B, char *ch_order, char *ch_Gx, char *ch_Gy, unsigned long cofactor, char *ch_name, char *oid);
328 int ecc_dp_set_bn(ltc_ecc_set_type *dp, void *a, void *b, void *prime, void *order, void *gx, void *gy, unsigned long cofactor);
329 int ecc_dp_set_by_oid(ltc_ecc_set_type *dp, unsigned long *oid, unsigned long oidsize);
330 int ecc_dp_fill_from_sets(ltc_ecc_set_type *dp);
331 int ecc_dp_clear(ltc_ecc_set_type *dp);
342 int ecc_get_set_by_name(const char* name, const ltc_ecc_set_type** dp);
343 int ecc_set_dp(const ltc_ecc_set_type *set, ecc_key *key);
344 int ecc_generate_key(prng_state *prng, int wprng, ecc_key *key);
345 int ecc_set_key(const unsigned char *in, unsigned long inlen, int type, ecc_key *key);
346 int ecc_get_key(unsigned char *out, unsigned long *outlen, int type, ecc_key *key);
332347
333348 int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key);
334349 int ecc_make_key_ex(prng_state *prng, int wprng, ecc_key *key, const ltc_ecc_set_type *dp);
337352 int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key);
338353 int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key);
339354 int ecc_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, const ltc_ecc_set_type *dp);
340 int ecc_import_pkcs8(const unsigned char *in, unsigned long inlen, const void *pwd, unsigned long pwdlen, ecc_key *key, ltc_ecc_set_type *dp);
341 int ecc_export_full(unsigned char *out, unsigned long *outlen, int type, ecc_key *key);
342 int ecc_import_full(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp);
343 int ecc_export_raw(unsigned char *out, unsigned long *outlen, int type, ecc_key *key);
344 int ecc_import_raw(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp);
345355
346356 int ecc_ansi_x963_export(ecc_key *key, unsigned char *out, unsigned long *outlen);
347357 int ecc_ansi_x963_import(const unsigned char *in, unsigned long inlen, ecc_key *key);
348 int ecc_ansi_x963_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp);
358 int ecc_ansi_x963_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, const ltc_ecc_set_type *dp);
359
360 int ecc_export_openssl(unsigned char *out, unsigned long *outlen, int type, ecc_key *key);
361 int ecc_import_openssl(const unsigned char *in, unsigned long inlen, ecc_key *key);
362 int ecc_import_pkcs8(const unsigned char *in, unsigned long inlen, const void *pwd, unsigned long pwdlen, ecc_key *key);
363 int ecc_import_x509(const unsigned char *in, unsigned long inlen, ecc_key *key);
349364
350365 int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key,
351366 unsigned char *out, unsigned long *outlen);
375390 const unsigned char *hash, unsigned long hashlen,
376391 int *stat, ecc_key *key);
377392
378 int ecc_verify_key(ecc_key *key);
393
394 #ifdef LTC_SOURCE
395 /* INTERNAL ONLY - it should be later moved to src/headers/tomcrypt_internal.h */
396
397 int ecc_set_dp_bn(void *a, void *b, void *prime, void *order, void *gx, void *gy, unsigned long cofactor, ecc_key *key);
398 int ecc_set_dp_oid(unsigned long *oid, unsigned long oidsize, ecc_key *key);
399 int ecc_set_dp_copy(ecc_key *srckey, ecc_key *key);
400 int ecc_set_dp_size(int size, ecc_key *key);
379401
380402 /* low level functions */
381403 ecc_point *ltc_ecc_new_point(void);
382404 void ltc_ecc_del_point(ecc_point *p);
383 int ltc_ecc_is_valid_idx(int n);
384 int ltc_ecc_is_point(const ltc_ecc_set_type *dp, void *x, void *y);
385 int ltc_ecc_is_point_at_infinity(ecc_point *p, void *modulus);
405 int ltc_ecc_is_point(const ltc_ecc_dp *dp, void *x, void *y);
406 int ltc_ecc_is_point_at_infinity(const ecc_point *p, void *modulus);
386407 int ltc_ecc_import_point(const unsigned char *in, unsigned long inlen, void *prime, void *a, void *b, void *x, void *y);
387408 int ltc_ecc_export_point(unsigned char *out, unsigned long *outlen, void *x, void *y, unsigned long size, int compressed);
409 int ltc_ecc_verify_key(ecc_key *key);
388410
389411 /* point ops (mp == montgomery digit) */
390412 #if !defined(LTC_MECC_ACCEL) || defined(LTM_DESC) || defined(GMP_DESC)
391413 /* R = 2P */
392 int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *a, void *modulus, void *mp);
414 int ltc_ecc_projective_dbl_point(const ecc_point *P, ecc_point *R, void *ma, void *modulus, void *mp);
393415
394416 /* R = P + Q */
395 int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *a, void *modulus, void *mp);
417 int ltc_ecc_projective_add_point(const ecc_point *P, const ecc_point *Q, ecc_point *R, void *ma, void *modulus, void *mp);
396418 #endif
397419
398420 #if defined(LTC_MECC_FP)
410432 #endif
411433
412434 /* R = kG */
413 int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *a, void *modulus, int map);
435 int ltc_ecc_mulmod(void *k, const ecc_point *G, ecc_point *R, void *a, void *modulus, int map);
414436
415437 #ifdef LTC_ECC_SHAMIR
416438 /* kA*A + kB*B = C */
417 int ltc_ecc_mul2add(ecc_point *A, void *kA,
418 ecc_point *B, void *kB,
419 ecc_point *C,
420 void *a,
421 void *modulus);
439 int ltc_ecc_mul2add(const ecc_point *A, void *kA,
440 const ecc_point *B, void *kB,
441 ecc_point *C,
442 void *ma,
443 void *modulus);
422444
423445 #ifdef LTC_MECC_FP
424446 /* Shamir's trick with optimized point multiplication using fixed point cache */
425 int ltc_ecc_fp_mul2add(ecc_point *A, void *kA,
426 ecc_point *B, void *kB,
427 ecc_point *C,
428 void *a,
429 void *modulus);
447 int ltc_ecc_fp_mul2add(const ecc_point *A, void *kA,
448 const ecc_point *B, void *kB,
449 ecc_point *C,
450 void *ma,
451 void *modulus);
430452 #endif
431453
432454 #endif
434456
435457 /* map P to affine from projective */
436458 int ltc_ecc_map(ecc_point *P, void *modulus, void *mp);
459
460 #endif /* LTC_SOURCE */
437461
438462 #endif
439463
548572 LTC_ASN1_SETOF,
549573 LTC_ASN1_RAW_BIT_STRING,
550574 LTC_ASN1_TELETEX_STRING,
551 LTC_ASN1_CONSTRUCTED,
552 LTC_ASN1_CONTEXT_SPECIFIC,
553 /* 20 */
554575 LTC_ASN1_GENERALIZEDTIME,
576 LTC_ASN1_CUSTOM_TYPE,
555577 } ltc_asn1_type;
578
579 typedef enum {
580 LTC_ASN1_CL_UNIVERSAL = 0x0,
581 LTC_ASN1_CL_APPLICATION = 0x1,
582 LTC_ASN1_CL_CONTEXT_SPECIFIC = 0x2,
583 LTC_ASN1_CL_PRIVATE = 0x3,
584 } ltc_asn1_class;
585
586 typedef enum {
587 LTC_ASN1_PC_PRIMITIVE = 0x0,
588 LTC_ASN1_PC_CONSTRUCTED = 0x1,
589 } ltc_asn1_pc;
556590
557591 /** A LTC ASN.1 list type */
558592 typedef struct ltc_asn1_list_ {
562596 void *data;
563597 /** The size of the input or resulting output */
564598 unsigned long size;
565 /** The used flag, this is used by the CHOICE ASN.1 type to indicate which choice was made */
599 /** The used flag
600 * 1. This is used by the CHOICE ASN.1 type to indicate which choice was made
601 * 2. This is used by the ASN.1 decoder to indicate if an element is used
602 * 3. This is used by the flexi-decoder to indicate the first byte of the identifier */
566603 int used;
567604 /** Flag used to indicate optional items in ASN.1 sequences */
568605 int optional;
569 /** Flag used to indicate context specific tags on ASN.1 sequence items */
570 unsigned char tag;
606 /** ASN.1 identifier */
607 ltc_asn1_class class;
608 ltc_asn1_pc pc;
609 ulong64 tag;
571610 /** prev/next entry in the list */
572611 struct ltc_asn1_list_ *prev, *next, *child, *parent;
573612 } ltc_asn1_list;
580619 LTC_MACRO_list[LTC_MACRO_temp].data = (void*)(Data); \
581620 LTC_MACRO_list[LTC_MACRO_temp].size = (Size); \
582621 LTC_MACRO_list[LTC_MACRO_temp].used = 0; \
622 LTC_MACRO_list[LTC_MACRO_temp].optional = 0; \
623 LTC_MACRO_list[LTC_MACRO_temp].class = 0; \
624 LTC_MACRO_list[LTC_MACRO_temp].pc = 0; \
583625 LTC_MACRO_list[LTC_MACRO_temp].tag = 0; \
584 LTC_MACRO_list[LTC_MACRO_temp].optional = 0; \
585626 } while (0)
627
628 #define __LTC_SET_ASN1_IDENTIFIER(list, index, Class, Pc, Tag) \
629 do { \
630 int LTC_MACRO_temp = (index); \
631 ltc_asn1_list *LTC_MACRO_list = (list); \
632 LTC_MACRO_list[LTC_MACRO_temp].type = LTC_ASN1_CUSTOM_TYPE; \
633 LTC_MACRO_list[LTC_MACRO_temp].class = (Class); \
634 LTC_MACRO_list[LTC_MACRO_temp].pc = (Pc); \
635 LTC_MACRO_list[LTC_MACRO_temp].tag = (Tag); \
636 } while (0)
637
638 #define LTC_SET_ASN1_CUSTOM_CONSTRUCTED(list, index, Class, Tag, Data) \
639 do { \
640 int LTC_MACRO_temp##__LINE__ = (index); \
641 LTC_SET_ASN1(list, LTC_MACRO_temp##__LINE__, LTC_ASN1_CUSTOM_TYPE, Data, 1); \
642 __LTC_SET_ASN1_IDENTIFIER(list, LTC_MACRO_temp##__LINE__, Class, LTC_ASN1_PC_CONSTRUCTED, Tag); \
643 } while (0)
644
645 #define LTC_SET_ASN1_CUSTOM_PRIMITIVE(list, index, Class, Tag, Type, Data, Size) \
646 do { \
647 int LTC_MACRO_temp##__LINE__ = (index); \
648 LTC_SET_ASN1(list, LTC_MACRO_temp##__LINE__, LTC_ASN1_CUSTOM_TYPE, Data, Size); \
649 __LTC_SET_ASN1_IDENTIFIER(list, LTC_MACRO_temp##__LINE__, Class, LTC_ASN1_PC_PRIMITIVE, Tag); \
650 list[LTC_MACRO_temp##__LINE__].used = (int)(Type); \
651 } while (0)
652
653 extern const char* der_asn1_class_to_string_map[];
654 extern const unsigned long der_asn1_class_to_string_map_sz;
655
656 extern const char* der_asn1_pc_to_string_map[];
657 extern const unsigned long der_asn1_pc_to_string_map_sz;
658
659 extern const char* der_asn1_tag_to_string_map[];
660 extern const unsigned long der_asn1_tag_to_string_map_sz;
586661
587662 /* SEQUENCE */
588663 int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen,
590665
591666 #define der_encode_sequence(list, inlen, out, outlen) der_encode_sequence_ex(list, inlen, out, outlen, LTC_ASN1_SEQUENCE)
592667
668 /** The supported bitmap for all the
669 * decoders with a `flags` argument.
670 */
671 enum ltc_der_seq {
672 LTC_DER_SEQ_ZERO = 0x0u,
673
674 /** Bit0 - [0]=Unordered (SET or SETOF)
675 * [1]=Ordered (SEQUENCE) */
676 LTC_DER_SEQ_UNORDERED = LTC_DER_SEQ_ZERO,
677 LTC_DER_SEQ_ORDERED = 0x1u,
678
679 /** Bit1 - [0]=Relaxed
680 * [1]=Strict */
681 LTC_DER_SEQ_RELAXED = LTC_DER_SEQ_ZERO,
682 LTC_DER_SEQ_STRICT = 0x2u,
683
684 /** Alternative naming */
685 LTC_DER_SEQ_SET = LTC_DER_SEQ_UNORDERED,
686 LTC_DER_SEQ_SEQUENCE = LTC_DER_SEQ_ORDERED,
687 };
688
593689 int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen,
594 ltc_asn1_list *list, unsigned long outlen, int ordered);
595
596 #define der_decode_sequence(in, inlen, list, outlen) der_decode_sequence_ex(in, inlen, list, outlen, 1)
690 ltc_asn1_list *list, unsigned long outlen, unsigned int flags);
691
692 #define der_decode_sequence(in, inlen, list, outlen) der_decode_sequence_ex(in, inlen, list, outlen, LTC_DER_SEQ_SEQUENCE | LTC_DER_SEQ_RELAXED)
693 #define der_decode_sequence_strict(in, inlen, list, outlen) der_decode_sequence_ex(in, inlen, list, outlen, LTC_DER_SEQ_SEQUENCE | LTC_DER_SEQ_STRICT)
597694
598695 int der_length_sequence(ltc_asn1_list *list, unsigned long inlen,
599696 unsigned long *outlen);
600697
601698
699 /* Custom-types */
700 int der_encode_custom_type(const ltc_asn1_list *root,
701 unsigned char *out, unsigned long *outlen);
702
703 int der_decode_custom_type(const unsigned char *in, unsigned long inlen,
704 ltc_asn1_list *root);
705
706 int der_length_custom_type(const ltc_asn1_list *root,
707 unsigned long *outlen,
708 unsigned long *payloadlen);
709
602710 #ifdef LTC_SOURCE
603711 /* internal helper functions */
712 int der_decode_custom_type_ex(const unsigned char *in, unsigned long inlen,
713 ltc_asn1_list *root,
714 ltc_asn1_list *list, unsigned long outlen, unsigned int flags);
715
716 int der_encode_asn1_identifier(const ltc_asn1_list *id, unsigned char *out, unsigned long *outlen);
717 int der_decode_asn1_identifier(const unsigned char *in, unsigned long *inlen, ltc_asn1_list *id);
718 int der_length_asn1_identifier(const ltc_asn1_list *id, unsigned long *idlen);
719
720 int der_encode_asn1_length(unsigned long len, unsigned char* out, unsigned long* outlen);
721 int der_decode_asn1_length(const unsigned char* len, unsigned long* lenlen, unsigned long* outlen);
722 int der_length_asn1_length(unsigned long len, unsigned long *outlen);
723
604724 int der_length_sequence_ex(ltc_asn1_list *list, unsigned long inlen,
605725 unsigned long *outlen, unsigned long *payloadlen);
606 /* SUBJECT PUBLIC KEY INFO */
607 int der_encode_subject_public_key_info(unsigned char *out, unsigned long *outlen,
608 unsigned int algorithm, void* public_key, unsigned long public_key_len,
609 unsigned long parameters_type, void* parameters, unsigned long parameters_len);
610
611 int der_decode_subject_public_key_info(const unsigned char *in, unsigned long inlen,
612 unsigned int algorithm, void* public_key, unsigned long* public_key_len,
613 unsigned long parameters_type, ltc_asn1_list* parameters, unsigned long parameters_len);
614
615 int der_decode_subject_public_key_info_ex(const unsigned char *in, unsigned long inlen,
616 unsigned int algorithm, void* public_key, unsigned long* public_key_len,
617 unsigned long parameters_type, void* parameters, unsigned long parameters_len,
618 unsigned long *parameters_outsize);
726
727 extern const ltc_asn1_type der_asn1_tag_to_type_map[];
728 extern const unsigned long der_asn1_tag_to_type_map_sz;
729
730 extern const int der_asn1_type_to_identifier_map[];
731 extern const unsigned long der_asn1_type_to_identifier_map_sz;
619732 #endif /* LTC_SOURCE */
620733
621734 /* SET */
622 #define der_decode_set(in, inlen, list, outlen) der_decode_sequence_ex(in, inlen, list, outlen, 0)
735 #define der_decode_set(in, inlen, list, outlen) der_decode_sequence_ex(in, inlen, list, outlen, LTC_DER_SEQ_SET)
623736 #define der_length_set der_length_sequence
624737 int der_encode_set(ltc_asn1_list *list, unsigned long inlen,
625738 unsigned char *out, unsigned long *outlen);
630743 /* VA list handy helpers with triplets of <type, size, data> */
631744 int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...);
632745 int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...);
746 #ifdef LTC_SOURCE
747 /* internal helper functions */
748 int der_decode_sequence_multi_ex(const unsigned char *in, unsigned long inlen, unsigned int flags, ...);
749 #endif /* LTC_SOURCE */
633750
634751 /* FLEXI DECODER handle unknown list decoder */
635752 int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out);
785902
786903 int der_length_generalizedtime(ltc_generalizedtime *gtime, unsigned long *outlen);
787904
905 #ifdef LTC_SOURCE
906 /* internal helper functions */
907 /* SUBJECT PUBLIC KEY INFO */
908 int x509_encode_subject_public_key_info(unsigned char *out, unsigned long *outlen,
909 unsigned int algorithm, void* public_key, unsigned long public_key_len,
910 unsigned long parameters_type, void* parameters, unsigned long parameters_len);
911
912 int x509_decode_subject_public_key_info(const unsigned char *in, unsigned long inlen,
913 unsigned int algorithm, void* public_key, unsigned long* public_key_len,
914 unsigned long parameters_type, void* parameters, unsigned long *parameters_len);
915 #endif /* LTC_SOURCE */
788916
789917 #endif
790918
2222 int blake2bmac_file(const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen)
2323 {
2424 #ifdef LTC_NO_FILE
25 LTC_UNUSED_PARAM(fname);
26 LTC_UNUSED_PARAM(key);
27 LTC_UNUSED_PARAM(keylen);
28 LTC_UNUSED_PARAM(mac);
29 LTC_UNUSED_PARAM(maclen);
2530 return CRYPT_NOP;
2631 #else
2732 blake2bmac_state st;
2222 int blake2smac_file(const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen)
2323 {
2424 #ifdef LTC_NO_FILE
25 LTC_UNUSED_PARAM(fname);
26 LTC_UNUSED_PARAM(key);
27 LTC_UNUSED_PARAM(keylen);
28 LTC_UNUSED_PARAM(mac);
29 LTC_UNUSED_PARAM(maclen);
2530 return CRYPT_NOP;
2631 #else
2732 blake2smac_state st;
3030 unsigned char *out, unsigned long *outlen)
3131 {
3232 #ifdef LTC_NO_FILE
33 LTC_UNUSED_PARAM(cipher);
34 LTC_UNUSED_PARAM(key);
35 LTC_UNUSED_PARAM(keylen);
36 LTC_UNUSED_PARAM(fname);
37 LTC_UNUSED_PARAM(out);
38 LTC_UNUSED_PARAM(outlen);
3339 return CRYPT_NOP;
3440 #else
3541 size_t x;
2929 unsigned char *out, unsigned long *outlen)
3030 {
3131 #ifdef LTC_NO_FILE
32 LTC_UNUSED_PARAM(hash);
33 LTC_UNUSED_PARAM(fname);
34 LTC_UNUSED_PARAM(key);
35 LTC_UNUSED_PARAM(keylen);
36 LTC_UNUSED_PARAM(out);
37 LTC_UNUSED_PARAM(outlen);
3238 return CRYPT_NOP;
3339 #else
3440 hmac_state hmac;
3030 unsigned char *out, unsigned long *outlen)
3131 {
3232 #ifdef LTC_NO_FILE
33 LTC_UNUSED_PARAM(cipher);
34 LTC_UNUSED_PARAM(key);
35 LTC_UNUSED_PARAM(keylen);
36 LTC_UNUSED_PARAM(filename);
37 LTC_UNUSED_PARAM(out);
38 LTC_UNUSED_PARAM(outlen);
3339 return CRYPT_NOP;
3440 #else
3541 size_t x;
3030 unsigned char *out, unsigned long *outlen)
3131 {
3232 #ifdef LTC_NO_FILE
33 LTC_UNUSED_PARAM(cipher);
34 LTC_UNUSED_PARAM(key);
35 LTC_UNUSED_PARAM(keylen);
36 LTC_UNUSED_PARAM(filename);
37 LTC_UNUSED_PARAM(out);
38 LTC_UNUSED_PARAM(outlen);
3339 return CRYPT_NOP;
3440 #else
3541 size_t x;
2727 int poly1305_file(const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen)
2828 {
2929 #ifdef LTC_NO_FILE
30 LTC_UNUSED_PARAM(fname);
31 LTC_UNUSED_PARAM(key);
32 LTC_UNUSED_PARAM(keylen);
33 LTC_UNUSED_PARAM(mac);
34 LTC_UNUSED_PARAM(maclen);
3035 return CRYPT_NOP;
3136 #else
3237 poly1305_state st;
3030 unsigned char *out, unsigned long *outlen)
3131 {
3232 #ifdef LTC_NO_FILE
33 LTC_UNUSED_PARAM(cipher);
34 LTC_UNUSED_PARAM(key);
35 LTC_UNUSED_PARAM(keylen);
36 LTC_UNUSED_PARAM(filename);
37 LTC_UNUSED_PARAM(out);
38 LTC_UNUSED_PARAM(outlen);
3339 return CRYPT_NOP;
3440 #else
3541 size_t x;
77 */
88 #include "tomcrypt.h"
99
10 #ifdef LTC_MDSA
10 #if defined(LTC_MDSA) || defined(LTC_MECC)
1111 /**
1212 Generate a random number N with given bitlength (note: MSB can be 0)
1313 */
264264 return CRYPT_OK;
265265 }
266266
267 /* sqrtmod_prime */
268 static int sqrtmod_prime(void *a, void *b, void *c)
269 {
270 LTC_ARGCHK(a != NULL);
271 LTC_ARGCHK(b != NULL);
272 LTC_ARGCHK(c != NULL);
273 fprintf(stderr, "TFM does not support sqrtmod_prime\n"); /* XXX-FIXME */
274 return CRYPT_ERROR;
275 }
276
267277 /* div */
268278 static int divide(void *a, void *b, void *c, void *d)
269279 {
423433
424434 #if defined(LTC_MECC) && defined(LTC_MECC_ACCEL)
425435
426 static int tfm_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void *Mp)
436 static int tfm_ecc_projective_dbl_point(const ecc_point *P, ecc_point *R, void *ma, void *modulus, void *Mp)
427437 {
428438 fp_int t1, t2;
429439 fp_digit mp;
442452 fp_copy(P->x, R->x);
443453 fp_copy(P->y, R->y);
444454 fp_copy(P->z, R->z);
455 }
456
457 if (ltc_ecc_is_point_at_infinity(P, modulus)) {
458 /* if P is point at infinity >> Result = point at infinity */
459 ltc_mp.set_int(R->x, 1);
460 ltc_mp.set_int(R->y, 1);
461 ltc_mp.set_int(R->z, 0);
462 return CRYPT_OK;
445463 }
446464
447465 /* t1 = Z * Z */
456474 fp_sub(R->z, modulus, R->z);
457475 }
458476
459 /* &t2 = X - T1 */
460 fp_sub(R->x, &t1, &t2);
461 if (fp_cmp_d(&t2, 0) == FP_LT) {
462 fp_add(&t2, modulus, &t2);
463 }
464 /* T1 = X + T1 */
465 fp_add(&t1, R->x, &t1);
466 if (fp_cmp(&t1, modulus) != FP_LT) {
467 fp_sub(&t1, modulus, &t1);
468 }
469 /* T2 = T1 * T2 */
470 fp_mul(&t1, &t2, &t2);
471 fp_montgomery_reduce(&t2, modulus, mp);
472 /* T1 = 2T2 */
473 fp_add(&t2, &t2, &t1);
474 if (fp_cmp(&t1, modulus) != FP_LT) {
475 fp_sub(&t1, modulus, &t1);
476 }
477 /* T1 = T1 + T2 */
478 fp_add(&t1, &t2, &t1);
479 if (fp_cmp(&t1, modulus) != FP_LT) {
480 fp_sub(&t1, modulus, &t1);
477 if (ma == NULL) { /* special case for curves with a == -3 (10% faster than general case) */
478 /* T2 = X - T1 */
479 fp_sub(R->x, &t1, &t2);
480 if (fp_cmp_d(&t2, 0) == LTC_MP_LT) {
481 fp_add(&t2, modulus, &t2);
482 }
483 /* T1 = X + T1 */
484 fp_add(&t1, R->x, &t1);
485 if (fp_cmp(&t1, modulus) != FP_LT) {
486 fp_sub(&t1, modulus, &t1);
487 }
488 /* T2 = T1 * T2 */
489 fp_mul(&t1, &t2, &t2);
490 fp_montgomery_reduce(&t2, modulus, mp);
491 /* T1 = 2T2 */
492 fp_add(&t2, &t2, &t1);
493 if (fp_cmp(&t1, modulus) != FP_LT) {
494 fp_sub(&t1, modulus, &t1);
495 }
496 /* T1 = T1 + T2 */
497 fp_add(&t1, &t2, &t1);
498 if (fp_cmp(&t1, modulus) != FP_LT) {
499 fp_sub(&t1, modulus, &t1);
500 }
501 }
502 else {
503 /* T2 = T1 * T1 */
504 fp_sqr(&t1, &t2);
505 fp_montgomery_reduce(&t2, modulus, mp);
506 /* T1 = T2 * a */
507 fp_mul(&t2, ma, &t1);
508 fp_montgomery_reduce(&t1, modulus, mp);
509 /* T2 = X * X */
510 fp_sqr(R->x, &t2);
511 fp_montgomery_reduce(&t2, modulus, mp);
512 /* T1 = T1 + T2 */
513 fp_add(&t1, &t2, &t1);
514 if (fp_cmp(&t1, modulus) != FP_LT) {
515 fp_sub(&t1, modulus, &t1);
516 }
517 /* T1 = T1 + T2 */
518 fp_add(&t1, &t2, &t1);
519 if (fp_cmp(&t1, modulus) != FP_LT) {
520 fp_sub(&t1, modulus, &t1);
521 }
522 /* T1 = T1 + T2 */
523 fp_add(&t1, &t2, &t1);
524 if (fp_cmp(&t1, modulus) != FP_LT) {
525 fp_sub(&t1, modulus, &t1);
526 }
481527 }
482528
483529 /* Y = 2Y */
540586 @param Mp The "b" value from montgomery_setup()
541587 @return CRYPT_OK on success
542588 */
543 static int tfm_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *Mp)
589 static int tfm_ecc_projective_add_point(const ecc_point *P, const ecc_point *Q, ecc_point *R, void *ma, void *modulus, void *Mp)
544590 {
545591 fp_int t1, t2, x, y, z;
546592 fp_digit mp;
559605 fp_init(&y);
560606 fp_init(&z);
561607
608 if (ltc_ecc_is_point_at_infinity(P, modulus)) {
609 /* P is point at infinity >> Result = Q */
610 ltc_mp.copy(Q->x, R->x);
611 ltc_mp.copy(Q->y, R->y);
612 ltc_mp.copy(Q->z, R->z);
613 return CRYPT_OK;
614 }
615
616 if (ltc_ecc_is_point_at_infinity(Q, modulus)) {
617 /* Q is point at infinity >> Result = P */
618 ltc_mp.copy(P->x, R->x);
619 ltc_mp.copy(P->y, R->y);
620 ltc_mp.copy(P->z, R->z);
621 return CRYPT_OK;
622 }
623
562624 /* should we dbl instead? */
563625 fp_sub(modulus, Q->y, &t1);
564626 if ( (fp_cmp(P->x, Q->x) == FP_EQ) &&
565627 (Q->z != NULL && fp_cmp(P->z, Q->z) == FP_EQ) &&
566628 (fp_cmp(P->y, Q->y) == FP_EQ || fp_cmp(P->y, &t1) == FP_EQ)) {
567 return tfm_ecc_projective_dbl_point(P, R, modulus, Mp);
629 return tfm_ecc_projective_dbl_point(P, R, ma, modulus, Mp);
568630 }
569631
570632 fp_copy(P->x, &x);
740802 &mul,
741803 &muli,
742804 &sqr,
805 &sqrtmod_prime,
743806 &divide,
744807 &div_2,
745808 &modi,
4646 _C_STRINGIFY(CRYPT_FILE_NOTFOUND),
4747 _C_STRINGIFY(CRYPT_PK_INVALID_TYPE),
4848 _C_STRINGIFY(CRYPT_OVERFLOW),
49 _C_STRINGIFY(CRYPT_UNUSED1),
49 _C_STRINGIFY(CRYPT_PK_ASN1_ERROR),
5050 _C_STRINGIFY(CRYPT_INPUT_TOO_LONG),
5151 _C_STRINGIFY(CRYPT_PK_INVALID_SIZE),
5252 _C_STRINGIFY(CRYPT_INVALID_PRIME_SIZE),
128128 _C_STRINGIFY(LTC_ASN1_SETOF),
129129 _C_STRINGIFY(LTC_ASN1_RAW_BIT_STRING),
130130 _C_STRINGIFY(LTC_ASN1_TELETEX_STRING),
131 _C_STRINGIFY(LTC_ASN1_CONSTRUCTED),
132 _C_STRINGIFY(LTC_ASN1_CONTEXT_SPECIFIC),
133131 _C_STRINGIFY(LTC_ASN1_GENERALIZEDTIME),
132 _C_STRINGIFY(LTC_ASN1_CUSTOM_TYPE),
134133 #endif
135134
136135 #ifdef LTC_CTR_MODE
4545
4646 "An overflow of a value was detected/prevented.",
4747
48 "UNUSED1.",
48 "An ASN.1 decoding error occurred.",
4949
5050 "The input was longer than expected.",
5151
4444 case PKA_EC:
4545 XMEMCPY(st, &ec_oid, sizeof(*st));
4646 break;
47 case EC_PRIME_FIELD:
47 case PKA_EC_PRIMEF:
4848 XMEMCPY(st, &ec_primef, sizeof(*st));
4949 break;
5050 default:
5252 if ((err = cipher_descriptor[ctr->cipher].accel_ctr_encrypt(pt, ct, len/ctr->blocklen, ctr->ctr, ctr->mode, &ctr->key)) != CRYPT_OK) {
5353 return err;
5454 }
55 pt += (len / ctr->blocklen) * ctr->blocklen;
56 ct += (len / ctr->blocklen) * ctr->blocklen;
5557 len %= ctr->blocklen;
5658 }
5759
2727 unsigned char *out, unsigned long *outlen)
2828 {
2929 unsigned long dlen, blen, x, y;
30 int err;
3031
3132 LTC_ARGCHK(in != NULL);
3233 LTC_ARGCHK(out != NULL);
4647 x = 1;
4748
4849 /* get the length of the data */
49 if (in[x] & 0x80) {
50 /* long format get number of length bytes */
51 y = in[x++] & 0x7F;
52
53 /* invalid if 0 or > 2 */
54 if (y == 0 || y > 2) {
55 return CRYPT_INVALID_PACKET;
56 }
57
58 /* read the data len */
59 dlen = 0;
60 while (y--) {
61 dlen = (dlen << 8) | (unsigned long)in[x++];
62 }
63 } else {
64 /* short format */
65 dlen = in[x++] & 0x7F;
50 y = inlen - 1;
51 if ((err = der_decode_asn1_length(in + x, &y, &dlen)) != CRYPT_OK) {
52 return err;
6653 }
67
54 x += y;
6855 /* is the data len too long or too short? */
69 if ((dlen == 0) || (dlen + x > inlen)) {
56 if ((dlen == 0) || (dlen > (inlen - x))) {
7057 return CRYPT_INVALID_PACKET;
7158 }
7259
3030 unsigned char *out, unsigned long *outlen)
3131 {
3232 unsigned long dlen, blen, x, y;
33 int err;
3334
3435 LTC_ARGCHK(in != NULL);
3536 LTC_ARGCHK(out != NULL);
4950 x = 1;
5051
5152 /* get the length of the data */
52 if (in[x] & 0x80) {
53 /* long format get number of length bytes */
54 y = in[x++] & 0x7F;
55
56 /* invalid if 0 or > 2 */
57 if (y == 0 || y > 2) {
58 return CRYPT_INVALID_PACKET;
59 }
60
61 /* read the data len */
62 dlen = 0;
63 while (y--) {
64 dlen = (dlen << 8) | (unsigned long)in[x++];
65 }
66 } else {
67 /* short format */
68 dlen = in[x++] & 0x7F;
53 y = inlen - 1;
54 if ((err = der_decode_asn1_length(in + x, &y, &dlen)) != CRYPT_OK) {
55 return err;
6956 }
70
57 x += y;
7158 /* is the data len too long or too short? */
72 if ((dlen == 0) || (dlen + x > inlen)) {
59 if ((dlen == 0) || (dlen > (inlen - x))) {
7360 return CRYPT_INVALID_PACKET;
7461 }
7562
4949 y = ((inlen + 7) >> 3) + 1;
5050
5151 out[x++] = 0x03;
52 if (y < 128) {
53 out[x++] = (unsigned char)y;
54 } else if (y < 256) {
55 out[x++] = 0x81;
56 out[x++] = (unsigned char)y;
57 } else if (y < 65536) {
58 out[x++] = 0x82;
59 out[x++] = (unsigned char)((y>>8)&255);
60 out[x++] = (unsigned char)(y&255);
52 len = *outlen - x;
53 if ((err = der_encode_asn1_length(y, out + x, &len)) != CRYPT_OK) {
54 return err;
6155 }
56 x += len;
6257
6358 /* store number of zero padding bits */
6459 out[x++] = (unsigned char)((8 - inlen) & 7);
5151 y = ((inlen + 7) >> 3) + 1;
5252
5353 out[x++] = 0x03;
54 if (y < 128) {
55 out[x++] = (unsigned char)y;
56 } else if (y < 256) {
57 out[x++] = 0x81;
58 out[x++] = (unsigned char)y;
59 } else if (y < 65536) {
60 out[x++] = 0x82;
61 out[x++] = (unsigned char)((y>>8)&255);
62 out[x++] = (unsigned char)(y&255);
54 len = *outlen - x;
55 if ((err = der_encode_asn1_length(y, out + x, &len)) != CRYPT_OK) {
56 return err;
6357 }
58 x += len;
6459
6560 /* store number of zero padding bits */
6661 out[x++] = (unsigned char)((8 - inlen) & 7);
2121 */
2222 int der_length_bit_string(unsigned long nbits, unsigned long *outlen)
2323 {
24 unsigned long nbytes;
24 unsigned long nbytes, x;
25 int err;
26
2527 LTC_ARGCHK(outlen != NULL);
2628
2729 /* get the number of the bytes */
2830 nbytes = (nbits >> 3) + ((nbits & 7) ? 1 : 0) + 1;
2931
30 if (nbytes < 128) {
31 /* 03 LL PP DD DD DD ... */
32 *outlen = 2 + nbytes;
33 } else if (nbytes < 256) {
34 /* 03 81 LL PP DD DD DD ... */
35 *outlen = 3 + nbytes;
36 } else if (nbytes < 65536) {
37 /* 03 82 LL LL PP DD DD DD ... */
38 *outlen = 4 + nbytes;
39 } else {
40 return CRYPT_INVALID_ARG;
32 if ((err = der_length_asn1_length(nbytes, &x)) != CRYPT_OK) {
33 return err;
4134 }
35 *outlen = 1 + x + nbytes;
4236
4337 return CRYPT_OK;
4438 }
204204 }
205205 break;
206206
207 case LTC_ASN1_CUSTOM_TYPE:
208 if (der_decode_custom_type(in, *inlen, &list[x]) == CRYPT_OK) {
209 if (der_length_custom_type(&list[x], &z, NULL) == CRYPT_OK) {
210 list[x].used = 1;
211 *inlen = z;
212 return CRYPT_OK;
213 }
214 }
215 break;
216
207217 case LTC_ASN1_CHOICE:
208 case LTC_ASN1_CONSTRUCTED:
209 case LTC_ASN1_CONTEXT_SPECIFIC:
210218 case LTC_ASN1_EOL:
211219 return CRYPT_INVALID_ARG;
212220 }
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 */
8 #include "tomcrypt.h"
9
10
11 /**
12 @file der_decode_custom_type.c
13 ASN.1 DER, decode a Custom type, Steffen Jaeckel
14 */
15
16 #ifdef LTC_DER
17
18 /**
19 Decode a Custom type
20 @param in The DER encoded input
21 @param inlen The size of the input
22 @param root The item that defines the custom type to decode
23 @return CRYPT_OK on success
24 */
25 int der_decode_custom_type(const unsigned char *in, unsigned long inlen,
26 ltc_asn1_list *root)
27 {
28 LTC_ARGCHK(root != NULL);
29 return der_decode_custom_type_ex(in, inlen, root, NULL, 0, LTC_DER_SEQ_ORDERED | LTC_DER_SEQ_RELAXED);
30 }
31
32 /**
33 Extended-decode a Custom type
34
35 This function is used to decode custom types and sequences/sets
36 For custom types root is used
37 For sequences/sets list and outlen are used
38
39 @param in The DER encoded input
40 @param inlen The size of the input
41 @param root The item that defines the custom type to decode
42 @param list The list of items to decode
43 @param outlen The number of items in the list
44 @param flags c.f. enum ltc_der_seq
45 @return CRYPT_OK on success
46 */
47 int der_decode_custom_type_ex(const unsigned char *in, unsigned long inlen,
48 ltc_asn1_list *root,
49 ltc_asn1_list *list, unsigned long outlen,
50 unsigned int flags)
51 {
52 int err, seq_err, i, ordered;
53 ltc_asn1_type type;
54 ltc_asn1_list ident;
55 unsigned long size, x, y, z, blksize;
56 unsigned char* in_new = NULL;
57 void *data;
58
59 LTC_ARGCHK(in != NULL);
60
61 /* get blk size */
62 if (inlen < 2) {
63 return CRYPT_INVALID_PACKET;
64 }
65 x = 0;
66
67 if (root == NULL) {
68 LTC_ARGCHK(list != NULL);
69
70 /* sequence type? We allow 0x30 SEQUENCE and 0x31 SET since fundamentally they're the same structure */
71 if (in[x] != 0x30 && in[x] != 0x31) {
72 return CRYPT_INVALID_PACKET;
73 }
74 ++x;
75 } else {
76 if (root->type != LTC_ASN1_CUSTOM_TYPE) {
77 return CRYPT_INVALID_PACKET;
78 }
79
80 /* Alloc a copy of the data for primitive handling. */
81 if (root->pc == LTC_ASN1_PC_PRIMITIVE) {
82 in_new = XMALLOC(inlen);
83 if (in_new == NULL) {
84 return CRYPT_MEM;
85 }
86 XMEMCPY(in_new, in, inlen);
87 in = in_new;
88 }
89
90 y = inlen;
91 if ((err = der_decode_asn1_identifier(in, &y, &ident)) != CRYPT_OK) {
92 goto LBL_ERR;
93 }
94 if ((ident.type != root->type) ||
95 (ident.class != root->class) ||
96 (ident.pc != root->pc) ||
97 (ident.tag != root->tag)) {
98 err = CRYPT_INVALID_PACKET;
99 goto LBL_ERR;
100 }
101 x += y;
102
103 list = root->data;
104 outlen = root->size;
105 }
106
107 if (root != NULL && root->pc == LTC_ASN1_PC_PRIMITIVE) {
108 if (((unsigned long)root->used >= der_asn1_type_to_identifier_map_sz) ||
109 (der_asn1_type_to_identifier_map[root->used] == -1)) {
110 err = CRYPT_INVALID_PACKET;
111 goto LBL_ERR;
112 }
113
114 root->type = (ltc_asn1_type)root->used;
115 list = root;
116 outlen = 1;
117
118 x -= 1;
119 in_new[x] = (unsigned char)der_asn1_type_to_identifier_map[list[0].type];
120 blksize = inlen - x;
121 } else {
122
123 y = inlen - x;
124 if ((err = der_decode_asn1_length(&in[x], &y, &blksize)) != CRYPT_OK) {
125 goto LBL_ERR;
126 }
127 x += y;
128 }
129
130 /* would this blksize overflow? */
131 if (blksize > (inlen - x)) {
132 err = CRYPT_INVALID_PACKET;
133 goto LBL_ERR;
134 }
135
136 /* mark all as unused */
137 for (i = 0; i < (int)outlen; i++) {
138 list[i].used = 0;
139 }
140 ordered = flags & LTC_DER_SEQ_ORDERED;
141
142 /* ok read data */
143 seq_err = CRYPT_OK;
144 blksize += x;
145 inlen -= x;
146 for (i = 0; i < (int)outlen; i++) {
147 z = 0;
148 type = list[i].type;
149 size = list[i].size;
150 data = list[i].data;
151 if (!ordered && list[i].used == 1) { continue; }
152
153 if (type == LTC_ASN1_EOL) {
154 break;
155 }
156
157 if (root != NULL && root->pc == LTC_ASN1_PC_PRIMITIVE && i != 0) {
158 err = CRYPT_PK_ASN1_ERROR;
159 goto LBL_ERR;
160 }
161
162 switch (type) {
163 case LTC_ASN1_BOOLEAN:
164 z = inlen;
165 if ((err = der_decode_boolean(in + x, z, ((int *)data))) != CRYPT_OK) {
166 if (!ordered || list[i].optional) { continue; }
167 goto LBL_ERR;
168 }
169 if ((err = der_length_boolean(&z)) != CRYPT_OK) {
170 goto LBL_ERR;
171 }
172 break;
173
174 case LTC_ASN1_INTEGER:
175 z = inlen;
176 if ((err = der_decode_integer(in + x, z, data)) != CRYPT_OK) {
177 if (!ordered || list[i].optional) { continue; }
178 goto LBL_ERR;
179 }
180 if ((err = der_length_integer(data, &z)) != CRYPT_OK) {
181 goto LBL_ERR;
182 }
183 break;
184
185 case LTC_ASN1_SHORT_INTEGER:
186 z = inlen;
187 if ((err = der_decode_short_integer(in + x, z, data)) != CRYPT_OK) {
188 if (!ordered || list[i].optional) { continue; }
189 goto LBL_ERR;
190 }
191 if ((err = der_length_short_integer(((unsigned long*)data)[0], &z)) != CRYPT_OK) {
192 goto LBL_ERR;
193 }
194
195 break;
196
197 case LTC_ASN1_BIT_STRING:
198 z = inlen;
199 if ((err = der_decode_bit_string(in + x, z, data, &size)) != CRYPT_OK) {
200 if (!ordered || list[i].optional) { continue; }
201 goto LBL_ERR;
202 }
203 list[i].size = size;
204 if ((err = der_length_bit_string(size, &z)) != CRYPT_OK) {
205 goto LBL_ERR;
206 }
207 break;
208
209 case LTC_ASN1_RAW_BIT_STRING:
210 z = inlen;
211 if ((err = der_decode_raw_bit_string(in + x, z, data, &size)) != CRYPT_OK) {
212 if (!ordered || list[i].optional) { continue; }
213 goto LBL_ERR;
214 }
215 list[i].size = size;
216 if ((err = der_length_bit_string(size, &z)) != CRYPT_OK) {
217 goto LBL_ERR;
218 }
219 break;
220
221 case LTC_ASN1_OCTET_STRING:
222 z = inlen;
223 if ((err = der_decode_octet_string(in + x, z, data, &size)) != CRYPT_OK) {
224 if (!ordered || list[i].optional) { continue; }
225 goto LBL_ERR;
226 }
227 list[i].size = size;
228 if ((err = der_length_octet_string(size, &z)) != CRYPT_OK) {
229 goto LBL_ERR;
230 }
231 break;
232
233 case LTC_ASN1_NULL:
234 if (inlen < 2 || in[x] != 0x05 || in[x+1] != 0x00) {
235 if (!ordered || list[i].optional) { continue; }
236 err = CRYPT_INVALID_PACKET;
237 goto LBL_ERR;
238 }
239 z = 2;
240 break;
241
242 case LTC_ASN1_OBJECT_IDENTIFIER:
243 z = inlen;
244 if ((err = der_decode_object_identifier(in + x, z, data, &size)) != CRYPT_OK) {
245 if (!ordered || list[i].optional) { continue; }
246 goto LBL_ERR;
247 }
248 list[i].size = size;
249 if ((err = der_length_object_identifier(data, size, &z)) != CRYPT_OK) {
250 goto LBL_ERR;
251 }
252 break;
253
254 case LTC_ASN1_TELETEX_STRING:
255 z = inlen;
256 if ((err = der_decode_teletex_string(in + x, z, data, &size)) != CRYPT_OK) {
257 if (!ordered || list[i].optional) { continue; }
258 goto LBL_ERR;
259 }
260 list[i].size = size;
261 if ((err = der_length_teletex_string(data, size, &z)) != CRYPT_OK) {
262 goto LBL_ERR;
263 }
264 break;
265
266 case LTC_ASN1_IA5_STRING:
267 z = inlen;
268 if ((err = der_decode_ia5_string(in + x, z, data, &size)) != CRYPT_OK) {
269 if (!ordered || list[i].optional) { continue; }
270 goto LBL_ERR;
271 }
272 list[i].size = size;
273 if ((err = der_length_ia5_string(data, size, &z)) != CRYPT_OK) {
274 goto LBL_ERR;
275 }
276 break;
277
278 case LTC_ASN1_PRINTABLE_STRING:
279 z = inlen;
280 if ((err = der_decode_printable_string(in + x, z, data, &size)) != CRYPT_OK) {
281 if (!ordered || list[i].optional) { continue; }
282 goto LBL_ERR;
283 }
284 list[i].size = size;
285 if ((err = der_length_printable_string(data, size, &z)) != CRYPT_OK) {
286 goto LBL_ERR;
287 }
288 break;
289
290 case LTC_ASN1_UTF8_STRING:
291 z = inlen;
292 if ((err = der_decode_utf8_string(in + x, z, data, &size)) != CRYPT_OK) {
293 if (!ordered || list[i].optional) { continue; }
294 goto LBL_ERR;
295 }
296 list[i].size = size;
297 if ((err = der_length_utf8_string(data, size, &z)) != CRYPT_OK) {
298 goto LBL_ERR;
299 }
300 break;
301
302 case LTC_ASN1_UTCTIME:
303 z = inlen;
304 if ((err = der_decode_utctime(in + x, &z, data)) != CRYPT_OK) {
305 if (!ordered || list[i].optional) { continue; }
306 goto LBL_ERR;
307 }
308 break;
309
310 case LTC_ASN1_GENERALIZEDTIME:
311 z = inlen;
312 if ((err = der_decode_generalizedtime(in + x, &z, data)) != CRYPT_OK) {
313 if (!ordered || list[i].optional) { continue; }
314 goto LBL_ERR;
315 }
316 break;
317
318 case LTC_ASN1_SET:
319 z = inlen;
320 if ((err = der_decode_set(in + x, z, data, size)) != CRYPT_OK) {
321 if (!ordered || list[i].optional) { continue; }
322 goto LBL_ERR;
323 }
324 if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) {
325 goto LBL_ERR;
326 }
327 break;
328
329 case LTC_ASN1_SETOF:
330 case LTC_ASN1_SEQUENCE:
331 /* detect if we have the right type */
332 if ((type == LTC_ASN1_SETOF && (in[x] & 0x3F) != 0x31) || (type == LTC_ASN1_SEQUENCE && (in[x] & 0x3F) != 0x30)) {
333 err = CRYPT_INVALID_PACKET;
334 goto LBL_ERR;
335 }
336
337 z = inlen;
338 err = der_decode_sequence_ex(in + x, z, data, size, flags);
339 if (err == CRYPT_INPUT_TOO_LONG) {
340 seq_err = CRYPT_INPUT_TOO_LONG;
341 err = CRYPT_OK;
342 }
343 if (err != CRYPT_OK) {
344 if (!ordered || list[i].optional) { continue; }
345 goto LBL_ERR;
346 }
347 if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) {
348 goto LBL_ERR;
349 }
350 break;
351
352 case LTC_ASN1_CUSTOM_TYPE:
353 z = inlen;
354 err = der_decode_custom_type(in + x, z, &list[i]);
355 if (err == CRYPT_INPUT_TOO_LONG) {
356 seq_err = CRYPT_INPUT_TOO_LONG;
357 err = CRYPT_OK;
358 }
359 if (err != CRYPT_OK) {
360 if (!ordered || list[i].optional) { continue; }
361 goto LBL_ERR;
362 }
363 if ((err = der_length_custom_type(&list[i], &z, NULL)) != CRYPT_OK) {
364 goto LBL_ERR;
365 }
366 break;
367
368 case LTC_ASN1_CHOICE:
369 z = inlen;
370 if ((err = der_decode_choice(in + x, &z, data, size)) != CRYPT_OK) {
371 if (!ordered || list[i].optional) { continue; }
372 goto LBL_ERR;
373 }
374 break;
375
376 case LTC_ASN1_EOL:
377 err = CRYPT_INVALID_ARG;
378 goto LBL_ERR;
379 }
380 x += z;
381 inlen -= z;
382 list[i].used = 1;
383 if (!ordered) {
384 /* restart the decoder */
385 i = -1;
386 }
387 }
388
389 for (i = 0; i < (int)outlen; i++) {
390 if (list[i].used == 0 && list[i].optional == 0) {
391 err = CRYPT_INVALID_PACKET;
392 goto LBL_ERR;
393 }
394 }
395
396 if (blksize == x && seq_err == CRYPT_OK && inlen == 0) {
397 /* everything decoded and no errors in nested sequences */
398 err = CRYPT_OK;
399 } else if (blksize == x && seq_err == CRYPT_INPUT_TOO_LONG && inlen == 0) {
400 /* a sequence reported too-long input, but now we've decoded everything */
401 err = CRYPT_OK;
402 } else if (blksize != x && ((flags & LTC_DER_SEQ_STRICT) == LTC_DER_SEQ_STRICT)) {
403 err = CRYPT_INVALID_PACKET;
404 } else {
405 err = CRYPT_INPUT_TOO_LONG;
406 }
407
408 LBL_ERR:
409 if (in_new != NULL) {
410 XFREE(in_new);
411 }
412 return err;
413 }
414
415 #endif
416
417 /* ref: $Format:%D$ */
418 /* git commit: $Format:%H$ */
419 /* commit time: $Format:%ai$ */
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 */
8 #include "tomcrypt.h"
9
10
11 /**
12 @file der_encode_custom_type.c
13 ASN.1 DER, encode a Custom Type, Steffen Jaeckel
14 */
15
16 #ifdef LTC_DER
17
18 /**
19 Encode a Custom Type
20
21 This function is a bit special compared to the others, as it requires the
22 root-ltc_asn1_list where the type is defined.
23
24 @param root The root of the list of items to encode
25 @param out [out] The destination
26 @param outlen [in/out] The size of the output
27 @return CRYPT_OK on success
28 */
29 int der_encode_custom_type(const ltc_asn1_list *root,
30 unsigned char *out, unsigned long *outlen)
31 {
32 int err;
33 ltc_asn1_type type;
34 const ltc_asn1_list *list;
35 unsigned long size, x, y, z, i, inlen, id_len;
36 void *data;
37
38 LTC_ARGCHK(root != NULL);
39 LTC_ARGCHK(out != NULL);
40 LTC_ARGCHK(outlen != NULL);
41
42 /* get size of output that will be required */
43 y = 0; z = 0;
44 if ((err = der_length_custom_type(root, &y, &z)) != CRYPT_OK) return CRYPT_INVALID_ARG;
45
46 /* too big ? */
47 if (*outlen < y) {
48 *outlen = y;
49 err = CRYPT_BUFFER_OVERFLOW;
50 goto LBL_ERR;
51 }
52
53 /* get length of the identifier, so we know the offset where to start writing */
54 if ((err = der_length_asn1_identifier(root, &id_len)) != CRYPT_OK) return CRYPT_INVALID_ARG;
55 x = id_len;
56
57
58 if (root->pc == LTC_ASN1_PC_PRIMITIVE) {
59 list = root;
60 inlen = 1;
61 /* In case it's a PRIMITIVE type we encode directly to the output
62 * but leave space for a potentially longer identifier as it will
63 * simply be replaced afterwards.
64 */
65 x -= 1;
66 } else {
67 list = root->data;
68 inlen = root->size;
69 /* store length, identifier will be added later */
70 y = *outlen - x;
71 if ((err = der_encode_asn1_length(z, &out[x], &y)) != CRYPT_OK) {
72 goto LBL_ERR;
73 }
74 x += y;
75 }
76
77 /* store data */
78 *outlen -= x;
79 for (i = 0; i < inlen; i++) {
80 if (root->pc == LTC_ASN1_PC_PRIMITIVE) {
81 type = (ltc_asn1_type)list[i].used;
82 } else {
83 type = list[i].type;
84 }
85 size = list[i].size;
86 data = list[i].data;
87
88 if (type == LTC_ASN1_EOL) {
89 break;
90 }
91
92 switch (type) {
93 case LTC_ASN1_BOOLEAN:
94 z = *outlen;
95 if ((err = der_encode_boolean(*((int *)data), out + x, &z)) != CRYPT_OK) {
96 goto LBL_ERR;
97 }
98 break;
99
100 case LTC_ASN1_INTEGER:
101 z = *outlen;
102 if ((err = der_encode_integer(data, out + x, &z)) != CRYPT_OK) {
103 goto LBL_ERR;
104 }
105 break;
106
107 case LTC_ASN1_SHORT_INTEGER:
108 z = *outlen;
109 if ((err = der_encode_short_integer(*((unsigned long*)data), out + x, &z)) != CRYPT_OK) {
110 goto LBL_ERR;
111 }
112 break;
113
114 case LTC_ASN1_BIT_STRING:
115 z = *outlen;
116 if ((err = der_encode_bit_string(data, size, out + x, &z)) != CRYPT_OK) {
117 goto LBL_ERR;
118 }
119 break;
120
121 case LTC_ASN1_RAW_BIT_STRING:
122 z = *outlen;
123 if ((err = der_encode_raw_bit_string(data, size, out + x, &z)) != CRYPT_OK) {
124 goto LBL_ERR;
125 }
126 break;
127
128 case LTC_ASN1_OCTET_STRING:
129 z = *outlen;
130 if ((err = der_encode_octet_string(data, size, out + x, &z)) != CRYPT_OK) {
131 goto LBL_ERR;
132 }
133 break;
134
135 case LTC_ASN1_NULL:
136 out[x] = 0x05;
137 out[x+1] = 0x00;
138 z = 2;
139 break;
140
141 case LTC_ASN1_OBJECT_IDENTIFIER:
142 z = *outlen;
143 if ((err = der_encode_object_identifier(data, size, out + x, &z)) != CRYPT_OK) {
144 goto LBL_ERR;
145 }
146 break;
147
148 case LTC_ASN1_IA5_STRING:
149 z = *outlen;
150 if ((err = der_encode_ia5_string(data, size, out + x, &z)) != CRYPT_OK) {
151 goto LBL_ERR;
152 }
153 break;
154
155 case LTC_ASN1_PRINTABLE_STRING:
156 z = *outlen;
157 if ((err = der_encode_printable_string(data, size, out + x, &z)) != CRYPT_OK) {
158 goto LBL_ERR;
159 }
160 break;
161
162 case LTC_ASN1_UTF8_STRING:
163 z = *outlen;
164 if ((err = der_encode_utf8_string(data, size, out + x, &z)) != CRYPT_OK) {
165 goto LBL_ERR;
166 }
167 break;
168
169 case LTC_ASN1_UTCTIME:
170 z = *outlen;
171 if ((err = der_encode_utctime(data, out + x, &z)) != CRYPT_OK) {
172 goto LBL_ERR;
173 }
174 break;
175
176 case LTC_ASN1_GENERALIZEDTIME:
177 z = *outlen;
178 if ((err = der_encode_generalizedtime(data, out + x, &z)) != CRYPT_OK) {
179 goto LBL_ERR;
180 }
181 break;
182
183 case LTC_ASN1_SET:
184 z = *outlen;
185 if ((err = der_encode_set(data, size, out + x, &z)) != CRYPT_OK) {
186 goto LBL_ERR;
187 }
188 break;
189
190 case LTC_ASN1_SETOF:
191 z = *outlen;
192 if ((err = der_encode_setof(data, size, out + x, &z)) != CRYPT_OK) {
193 goto LBL_ERR;
194 }
195 break;
196
197 case LTC_ASN1_SEQUENCE:
198 z = *outlen;
199 if ((err = der_encode_sequence_ex(data, size, out + x, &z, type)) != CRYPT_OK) {
200 goto LBL_ERR;
201 }
202 break;
203
204 case LTC_ASN1_CUSTOM_TYPE:
205 z = *outlen;
206 if ((err = der_encode_custom_type(&list[i], out + x, &z)) != CRYPT_OK) {
207 goto LBL_ERR;
208 }
209 break;
210
211 case LTC_ASN1_CHOICE:
212