ltc sync
Karel Miko
7 years ago
57 | 57 | |
58 | 58 | data = (unsigned char *)SvPVbyte(key_data, data_len); |
59 | 59 | _ecc_free_key(&self->key, &self->dp); |
60 | rv = ecc_import_pkcs8(data, (unsigned long)data_len, &self->key, &self->dp); | |
60 | rv = ecc_import_pkcs8(data, (unsigned long)data_len, NULL, 0, &self->key, &self->dp); | |
61 | 61 | if (rv != CRYPT_OK) croak("FATAL: ecc_import_pkcs8 failed: %s", error_to_string(rv)); |
62 | 62 | XPUSHs(ST(0)); /* return self */ |
63 | 63 | } |
55 | 55 | |
56 | 56 | data = (unsigned char *)SvPVbyte(key_data, data_len); |
57 | 57 | if (self->key.type != -1) { rsa_free(&self->key); self->key.type = -1; } |
58 | rv = rsa_import_pkcs8(data, (unsigned long)data_len, &self->key); | |
58 | rv = rsa_import_pkcs8(data, (unsigned long)data_len, NULL, 0, &self->key); | |
59 | 59 | if (rv != CRYPT_OK) croak("FATAL: rsa_import_pkcs8 failed: %s", error_to_string(rv)); |
60 | 60 | XPUSHs(ST(0)); /* return self */ |
61 | 61 | } |
1 | 1 | ltc/ciphers/des.o ltc/ciphers/kasumi.o ltc/ciphers/khazad.o ltc/ciphers/kseed.o ltc/ciphers/multi2.o \ |
2 | 2 | ltc/ciphers/noekeon.o ltc/ciphers/rc2.o ltc/ciphers/rc5.o ltc/ciphers/rc6.o ltc/ciphers/safer/safer.o \ |
3 | 3 | ltc/ciphers/safer/saferp.o ltc/ciphers/skipjack.o ltc/ciphers/twofish/twofish.o ltc/ciphers/xtea.o \ |
4 | ltc/stream/chacha/chacha_crypt.o ltc/stream/chacha/chacha_done.o ltc/stream/chacha/chacha_ivctr32.o \ | |
5 | ltc/stream/chacha/chacha_ivctr64.o ltc/stream/chacha/chacha_keystream.o ltc/stream/chacha/chacha_setup.o \ | |
6 | ltc/encauth/chachapoly/chacha20poly1305_add_aad.o ltc/encauth/chachapoly/chacha20poly1305_decrypt.o \ | |
7 | ltc/encauth/chachapoly/chacha20poly1305_done.o ltc/encauth/chachapoly/chacha20poly1305_encrypt.o \ | |
8 | ltc/encauth/chachapoly/chacha20poly1305_init.o ltc/encauth/chachapoly/chacha20poly1305_memory.o \ | |
9 | ltc/encauth/chachapoly/chacha20poly1305_setiv.o ltc/encauth/chachapoly/chacha20poly1305_setiv_rfc7905.o \ | |
4 | 10 | ltc/encauth/ccm/ccm_add_aad.o ltc/encauth/ccm/ccm_add_nonce.o ltc/encauth/ccm/ccm_done.o ltc/encauth/ccm/ccm_init.o \ |
5 | ltc/encauth/ccm/ccm_memory.o ltc/encauth/ccm/ccm_memory_ex.o ltc/encauth/ccm/ccm_process.o ltc/encauth/ccm/ccm_reset.o \ | |
11 | ltc/encauth/ccm/ccm_memory.o ltc/encauth/ccm/ccm_process.o ltc/encauth/ccm/ccm_reset.o \ | |
6 | 12 | ltc/encauth/eax/eax_addheader.o ltc/encauth/eax/eax_decrypt.o ltc/encauth/eax/eax_decrypt_verify_memory.o \ |
7 | 13 | ltc/encauth/eax/eax_done.o ltc/encauth/eax/eax_encrypt.o ltc/encauth/eax/eax_encrypt_authenticate_memory.o \ |
8 | 14 | ltc/encauth/eax/eax_init.o ltc/encauth/gcm/gcm_add_aad.o ltc/encauth/gcm/gcm_add_iv.o ltc/encauth/gcm/gcm_done.o \ |
16 | 22 | ltc/hashes/helper/hash_memory_multi.o ltc/hashes/md2.o ltc/hashes/md4.o ltc/hashes/md5.o ltc/hashes/rmd128.o \ |
17 | 23 | ltc/hashes/rmd160.o ltc/hashes/rmd256.o ltc/hashes/rmd320.o ltc/hashes/sha1.o ltc/hashes/sha2/sha224.o \ |
18 | 24 | ltc/hashes/sha2/sha256.o ltc/hashes/sha2/sha384.o ltc/hashes/sha2/sha512.o ltc/hashes/sha2/sha512_224.o \ |
19 | ltc/hashes/sha2/sha512_256.o ltc/hashes/tiger.o ltc/hashes/whirl/whirl.o ltc/mac/f9/f9_done.o ltc/mac/f9/f9_file.o \ | |
20 | ltc/mac/f9/f9_init.o ltc/mac/f9/f9_memory.o ltc/mac/f9/f9_memory_multi.o ltc/mac/f9/f9_process.o \ | |
25 | ltc/hashes/sha2/sha512_256.o ltc/hashes/tiger.o ltc/hashes/whirl/whirl.o ltc/hashes/sha3.o \ | |
26 | ltc/mac/poly1305/poly1305.o ltc/mac/poly1305/poly1305_file.o ltc/mac/poly1305/poly1305_memory.o ltc/mac/poly1305/poly1305_memory_multi.o \ | |
27 | ltc/mac/f9/f9_done.o ltc/mac/f9/f9_file.o ltc/mac/f9/f9_init.o ltc/mac/f9/f9_memory.o ltc/mac/f9/f9_memory_multi.o ltc/mac/f9/f9_process.o \ | |
21 | 28 | ltc/mac/hmac/hmac_done.o ltc/mac/hmac/hmac_file.o ltc/mac/hmac/hmac_init.o ltc/mac/hmac/hmac_memory.o \ |
22 | 29 | ltc/mac/hmac/hmac_memory_multi.o ltc/mac/hmac/hmac_process.o ltc/mac/omac/omac_done.o ltc/mac/omac/omac_file.o \ |
23 | 30 | ltc/mac/omac/omac_init.o ltc/mac/omac/omac_memory.o ltc/mac/omac/omac_memory_multi.o ltc/mac/omac/omac_process.o \ |
49 | 56 | ltc/pk/asn1/der/bit/der_length_bit_string.o ltc/pk/asn1/der/boolean/der_decode_boolean.o \ |
50 | 57 | ltc/pk/asn1/der/boolean/der_encode_boolean.o ltc/pk/asn1/der/boolean/der_length_boolean.o \ |
51 | 58 | ltc/pk/asn1/der/choice/der_decode_choice.o ltc/pk/asn1/der/ia5/der_decode_ia5_string.o \ |
59 | ltc/pk/asn1/der/generalizedtime/der_decode_generalizedtime.o ltc/pk/asn1/der/generalizedtime/der_encode_generalizedtime.o \ | |
60 | ltc/pk/asn1/der/generalizedtime/der_length_generalizedtime.o \ | |
52 | 61 | ltc/pk/asn1/der/ia5/der_encode_ia5_string.o ltc/pk/asn1/der/ia5/der_length_ia5_string.o \ |
53 | 62 | ltc/pk/asn1/der/integer/der_decode_integer.o ltc/pk/asn1/der/integer/der_encode_integer.o \ |
54 | 63 | ltc/pk/asn1/der/integer/der_length_integer.o ltc/pk/asn1/der/object_identifier/der_decode_object_identifier.o \ |
83 | 92 | ltc/pk/ecc/ltc_ecc_is_valid_idx.o ltc/pk/ecc/ltc_ecc_map.o ltc/pk/ecc/ltc_ecc_mul2add.o ltc/pk/ecc/ltc_ecc_mulmod.o \ |
84 | 93 | ltc/pk/ecc/ltc_ecc_mulmod_timing.o ltc/pk/ecc/ltc_ecc_points.o ltc/pk/ecc/ltc_ecc_projective_add_point.o \ |
85 | 94 | ltc/pk/ecc/ltc_ecc_projective_dbl_point.o ltc/pk/pkcs1/pkcs_1_i2osp.o ltc/pk/pkcs1/pkcs_1_mgf1.o \ |
95 | ltc/pk/ecc/ltc_ecc_export_point.o ltc/pk/ecc/ltc_ecc_import_point.o ltc/pk/ecc/ltc_ecc_is_point_at_infinity.o \ | |
86 | 96 | ltc/pk/pkcs1/pkcs_1_oaep_decode.o ltc/pk/pkcs1/pkcs_1_oaep_encode.o ltc/pk/pkcs1/pkcs_1_os2ip.o \ |
87 | 97 | 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 \ |
88 | 98 | ltc/pk/pkcs1/pkcs_1_v1_5_encode.o ltc/pk/rsa/rsa_decrypt_key.o ltc/pk/rsa/rsa_encrypt_key.o ltc/pk/rsa/rsa_export.o \ |
89 | 99 | 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 \ |
90 | ltc/pk/rsa/rsa_import_radix.o ltc/pk/rsa/rsa_import_pkcs8.o ltc/pk/rsa/rsa_make_key.o ltc/pk/rsa/rsa_sign_hash.o \ | |
100 | ltc/pk/rsa/rsa_import_radix.o ltc/pk/rsa/rsa_import_pkcs8.o ltc/pk/rsa/rsa_import_x509.o ltc/pk/rsa/rsa_make_key.o ltc/pk/rsa/rsa_sign_hash.o \ | |
91 | 101 | ltc/pk/rsa/rsa_sign_saltlen_get.o ltc/pk/rsa/rsa_verify_hash.o ltc/prngs/fortuna.o ltc/prngs/rc4.o \ |
92 | ltc/prngs/rng_get_bytes.o ltc/prngs/rng_make_prng.o ltc/prngs/sober128.o ltc/prngs/sprng.o ltc/prngs/yarrow.o \ | |
102 | ltc/prngs/rng_get_bytes.o ltc/prngs/rng_make_prng.o ltc/prngs/sober128.o ltc/prngs/sprng.o ltc/prngs/yarrow.o ltc/prngs/chacha20.o \ | |
93 | 103 | ltm/bn_error.o ltm/bn_fast_mp_invmod.o ltm/bn_fast_mp_montgomery_reduce.o ltm/bn_fast_s_mp_mul_digs.o \ |
94 | 104 | ltm/bn_fast_s_mp_mul_high_digs.o ltm/bn_fast_s_mp_sqr.o ltm/bn_mp_2expt.o ltm/bn_mp_abs.o ltm/bn_mp_add.o \ |
95 | 105 | ltm/bn_mp_add_d.o ltm/bn_mp_addmod.o ltm/bn_mp_and.o ltm/bn_mp_clamp.o ltm/bn_mp_clear.o ltm/bn_mp_clear_multi.o \ |
1 | 1 | ltc/ciphers/des.obj ltc/ciphers/kasumi.obj ltc/ciphers/khazad.obj ltc/ciphers/kseed.obj ltc/ciphers/multi2.obj \ |
2 | 2 | ltc/ciphers/noekeon.obj ltc/ciphers/rc2.obj ltc/ciphers/rc5.obj ltc/ciphers/rc6.obj ltc/ciphers/safer/safer.obj \ |
3 | 3 | ltc/ciphers/safer/saferp.obj ltc/ciphers/skipjack.obj ltc/ciphers/twofish/twofish.obj ltc/ciphers/xtea.obj \ |
4 | ltc/stream/chacha/chacha_crypt.obj ltc/stream/chacha/chacha_done.obj ltc/stream/chacha/chacha_ivctr32.obj \ | |
5 | ltc/stream/chacha/chacha_ivctr64.obj ltc/stream/chacha/chacha_keystream.obj ltc/stream/chacha/chacha_setup.obj \ | |
6 | ltc/encauth/chachapoly/chacha20poly1305_add_aad.obj ltc/encauth/chachapoly/chacha20poly1305_decrypt.obj \ | |
7 | ltc/encauth/chachapoly/chacha20poly1305_done.obj ltc/encauth/chachapoly/chacha20poly1305_encrypt.obj \ | |
8 | ltc/encauth/chachapoly/chacha20poly1305_init.obj ltc/encauth/chachapoly/chacha20poly1305_memory.obj \ | |
9 | ltc/encauth/chachapoly/chacha20poly1305_setiv.obj ltc/encauth/chachapoly/chacha20poly1305_setiv_rfc7905.obj \ | |
4 | 10 | ltc/encauth/ccm/ccm_add_aad.obj ltc/encauth/ccm/ccm_add_nonce.obj ltc/encauth/ccm/ccm_done.obj ltc/encauth/ccm/ccm_init.obj \ |
5 | ltc/encauth/ccm/ccm_memory.obj ltc/encauth/ccm/ccm_memory_ex.obj ltc/encauth/ccm/ccm_process.obj ltc/encauth/ccm/ccm_reset.obj \ | |
11 | ltc/encauth/ccm/ccm_memory.obj ltc/encauth/ccm/ccm_process.obj ltc/encauth/ccm/ccm_reset.obj \ | |
6 | 12 | ltc/encauth/eax/eax_addheader.obj ltc/encauth/eax/eax_decrypt.obj ltc/encauth/eax/eax_decrypt_verify_memory.obj \ |
7 | 13 | ltc/encauth/eax/eax_done.obj ltc/encauth/eax/eax_encrypt.obj ltc/encauth/eax/eax_encrypt_authenticate_memory.obj \ |
8 | 14 | ltc/encauth/eax/eax_init.obj ltc/encauth/gcm/gcm_add_aad.obj ltc/encauth/gcm/gcm_add_iv.obj ltc/encauth/gcm/gcm_done.obj \ |
16 | 22 | ltc/hashes/helper/hash_memory_multi.obj ltc/hashes/md2.obj ltc/hashes/md4.obj ltc/hashes/md5.obj ltc/hashes/rmd128.obj \ |
17 | 23 | ltc/hashes/rmd160.obj ltc/hashes/rmd256.obj ltc/hashes/rmd320.obj ltc/hashes/sha1.obj ltc/hashes/sha2/sha224.obj \ |
18 | 24 | ltc/hashes/sha2/sha256.obj ltc/hashes/sha2/sha384.obj ltc/hashes/sha2/sha512.obj ltc/hashes/sha2/sha512_224.obj \ |
19 | ltc/hashes/sha2/sha512_256.obj ltc/hashes/tiger.obj ltc/hashes/whirl/whirl.obj ltc/mac/f9/f9_done.obj ltc/mac/f9/f9_file.obj \ | |
20 | ltc/mac/f9/f9_init.obj ltc/mac/f9/f9_memory.obj ltc/mac/f9/f9_memory_multi.obj ltc/mac/f9/f9_process.obj \ | |
25 | ltc/hashes/sha2/sha512_256.obj ltc/hashes/tiger.obj ltc/hashes/whirl/whirl.obj ltc/hashes/sha3.obj \ | |
26 | ltc/mac/poly1305/poly1305.obj ltc/mac/poly1305/poly1305_file.obj ltc/mac/poly1305/poly1305_memory.obj ltc/mac/poly1305/poly1305_memory_multi.obj \ | |
27 | ltc/mac/f9/f9_done.obj ltc/mac/f9/f9_file.obj ltc/mac/f9/f9_init.obj ltc/mac/f9/f9_memory.obj ltc/mac/f9/f9_memory_multi.obj ltc/mac/f9/f9_process.obj \ | |
21 | 28 | ltc/mac/hmac/hmac_done.obj ltc/mac/hmac/hmac_file.obj ltc/mac/hmac/hmac_init.obj ltc/mac/hmac/hmac_memory.obj \ |
22 | 29 | ltc/mac/hmac/hmac_memory_multi.obj ltc/mac/hmac/hmac_process.obj ltc/mac/omac/omac_done.obj ltc/mac/omac/omac_file.obj \ |
23 | 30 | ltc/mac/omac/omac_init.obj ltc/mac/omac/omac_memory.obj ltc/mac/omac/omac_memory_multi.obj ltc/mac/omac/omac_process.obj \ |
49 | 56 | ltc/pk/asn1/der/bit/der_length_bit_string.obj ltc/pk/asn1/der/boolean/der_decode_boolean.obj \ |
50 | 57 | ltc/pk/asn1/der/boolean/der_encode_boolean.obj ltc/pk/asn1/der/boolean/der_length_boolean.obj \ |
51 | 58 | ltc/pk/asn1/der/choice/der_decode_choice.obj ltc/pk/asn1/der/ia5/der_decode_ia5_string.obj \ |
59 | ltc/pk/asn1/der/generalizedtime/der_decode_generalizedtime.obj ltc/pk/asn1/der/generalizedtime/der_encode_generalizedtime.obj \ | |
60 | ltc/pk/asn1/der/generalizedtime/der_length_generalizedtime.obj \ | |
52 | 61 | ltc/pk/asn1/der/ia5/der_encode_ia5_string.obj ltc/pk/asn1/der/ia5/der_length_ia5_string.obj \ |
53 | 62 | ltc/pk/asn1/der/integer/der_decode_integer.obj ltc/pk/asn1/der/integer/der_encode_integer.obj \ |
54 | 63 | ltc/pk/asn1/der/integer/der_length_integer.obj ltc/pk/asn1/der/object_identifier/der_decode_object_identifier.obj \ |
83 | 92 | ltc/pk/ecc/ltc_ecc_is_valid_idx.obj ltc/pk/ecc/ltc_ecc_map.obj ltc/pk/ecc/ltc_ecc_mul2add.obj ltc/pk/ecc/ltc_ecc_mulmod.obj \ |
84 | 93 | ltc/pk/ecc/ltc_ecc_mulmod_timing.obj ltc/pk/ecc/ltc_ecc_points.obj ltc/pk/ecc/ltc_ecc_projective_add_point.obj \ |
85 | 94 | ltc/pk/ecc/ltc_ecc_projective_dbl_point.obj ltc/pk/pkcs1/pkcs_1_i2osp.obj ltc/pk/pkcs1/pkcs_1_mgf1.obj \ |
95 | ltc/pk/ecc/ltc_ecc_export_point.obj ltc/pk/ecc/ltc_ecc_import_point.obj ltc/pk/ecc/ltc_ecc_is_point_at_infinity.obj \ | |
86 | 96 | ltc/pk/pkcs1/pkcs_1_oaep_decode.obj ltc/pk/pkcs1/pkcs_1_oaep_encode.obj ltc/pk/pkcs1/pkcs_1_os2ip.obj \ |
87 | 97 | 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 \ |
88 | 98 | ltc/pk/pkcs1/pkcs_1_v1_5_encode.obj ltc/pk/rsa/rsa_decrypt_key.obj ltc/pk/rsa/rsa_encrypt_key.obj ltc/pk/rsa/rsa_export.obj \ |
89 | 99 | 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 \ |
90 | ltc/pk/rsa/rsa_import_radix.obj ltc/pk/rsa/rsa_import_pkcs8.obj ltc/pk/rsa/rsa_make_key.obj ltc/pk/rsa/rsa_sign_hash.obj \ | |
100 | ltc/pk/rsa/rsa_import_radix.obj ltc/pk/rsa/rsa_import_pkcs8.obj ltc/pk/rsa/rsa_import_x509.obj ltc/pk/rsa/rsa_make_key.obj ltc/pk/rsa/rsa_sign_hash.obj \ | |
91 | 101 | ltc/pk/rsa/rsa_sign_saltlen_get.obj ltc/pk/rsa/rsa_verify_hash.obj ltc/prngs/fortuna.obj ltc/prngs/rc4.obj \ |
92 | ltc/prngs/rng_get_bytes.obj ltc/prngs/rng_make_prng.obj ltc/prngs/sober128.obj ltc/prngs/sprng.obj ltc/prngs/yarrow.obj \ | |
102 | ltc/prngs/rng_get_bytes.obj ltc/prngs/rng_make_prng.obj ltc/prngs/sober128.obj ltc/prngs/sprng.obj ltc/prngs/yarrow.obj ltc/prngs/chacha20.obj \ | |
93 | 103 | ltm/bn_error.obj ltm/bn_fast_mp_invmod.obj ltm/bn_fast_mp_montgomery_reduce.obj ltm/bn_fast_s_mp_mul_digs.obj \ |
94 | 104 | ltm/bn_fast_s_mp_mul_high_digs.obj ltm/bn_fast_s_mp_sqr.obj ltm/bn_mp_2expt.obj ltm/bn_mp_abs.obj ltm/bn_mp_add.obj \ |
95 | 105 | ltm/bn_mp_add_d.obj ltm/bn_mp_addmod.obj ltm/bn_mp_and.obj ltm/bn_mp_clamp.obj ltm/bn_mp_clear.obj ltm/bn_mp_clear_multi.obj \ |
369 | 369 | rc2_ecb_encrypt(tests[x].pt, tmp[0], &skey); |
370 | 370 | rc2_ecb_decrypt(tmp[0], tmp[1], &skey); |
371 | 371 | |
372 | if (compare_testvector(tmp[0], 8, tests[x].ct, 8, "RC2 CT", x) != 0 || | |
373 | compare_testvector(tmp[1], 8, tests[x].pt, 8, "RC2 PT", x) != 0) { | |
372 | if (compare_testvector(tmp[0], 8, tests[x].ct, 8, "RC2 CT", x) || | |
373 | compare_testvector(tmp[1], 8, tests[x].pt, 8, "RC2 PT", x)) { | |
374 | 374 | return CRYPT_FAIL_TESTVECTOR; |
375 | 375 | } |
376 | 376 |
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 | * Tom St Denis, tomstdenis@gmail.com, http://libtom.org | |
9 | */ | |
10 | #include "tomcrypt.h" | |
11 | ||
12 | /** | |
13 | @file ccm_memory.c | |
14 | CCM support, process a block of memory, Tom St Denis | |
15 | */ | |
16 | ||
17 | #if defined LTC_CCM_MODE && 0 | |
18 | ||
19 | /** | |
20 | CCM encrypt/decrypt and produce an authentication tag | |
21 | @param cipher The index of the cipher desired | |
22 | @param key The secret key to use | |
23 | @param keylen The length of the secret key (octets) | |
24 | @param uskey A previously scheduled key [optional can be NULL] | |
25 | @param nonce The session nonce [use once] | |
26 | @param noncelen The length of the nonce | |
27 | @param header The header for the session | |
28 | @param headerlen The length of the header (octets) | |
29 | @param pt [out] The plaintext | |
30 | @param ptlen The length of the plaintext (octets) | |
31 | @param ct [out] The ciphertext | |
32 | @param tag [out] The destination tag | |
33 | @param taglen [in/out] The max size and resulting size of the authentication tag | |
34 | @param direction Encrypt or Decrypt direction (0 or 1) | |
35 | @return CRYPT_OK if successful | |
36 | */ | |
37 | int ccm_memory_ex(int cipher, | |
38 | const unsigned char *key, unsigned long keylen, | |
39 | symmetric_key *uskey, | |
40 | const unsigned char *nonce, unsigned long noncelen, | |
41 | const unsigned char *header, unsigned long headerlen, | |
42 | unsigned char *pt, unsigned long ptlen, | |
43 | unsigned char *ct, | |
44 | unsigned char *tag, unsigned long *taglen, | |
45 | int direction, | |
46 | const unsigned char *B_0, | |
47 | const unsigned char *CTR, | |
48 | int ctrwidth) | |
49 | { | |
50 | unsigned char PAD[16], ctr[16], CTRPAD[16], ctrcopy[16], b; | |
51 | symmetric_key *skey; | |
52 | int err; | |
53 | unsigned long len, L, x, y, z, CTRlen; | |
54 | ||
55 | if (uskey == NULL) { | |
56 | LTC_ARGCHK(key != NULL); | |
57 | } | |
58 | LTC_ARGCHK(nonce != NULL); | |
59 | if (headerlen > 0) { | |
60 | LTC_ARGCHK(header != NULL); | |
61 | } | |
62 | LTC_ARGCHK(pt != NULL); | |
63 | LTC_ARGCHK(ct != NULL); | |
64 | LTC_ARGCHK(tag != NULL); | |
65 | LTC_ARGCHK(taglen != NULL); | |
66 | ||
67 | #ifdef LTC_FAST | |
68 | if (16 % sizeof(LTC_FAST_TYPE)) { | |
69 | return CRYPT_INVALID_ARG; | |
70 | } | |
71 | #endif | |
72 | ||
73 | /* check cipher input */ | |
74 | if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { | |
75 | return err; | |
76 | } | |
77 | if (cipher_descriptor[cipher].block_length != 16) { | |
78 | return CRYPT_INVALID_CIPHER; | |
79 | } | |
80 | ||
81 | /* make sure the taglen is even and <= 16 */ | |
82 | *taglen &= ~1; | |
83 | if (*taglen > 16) { | |
84 | *taglen = 16; | |
85 | } | |
86 | ||
87 | /* can't use < 4 */ | |
88 | if (*taglen < 4) { | |
89 | return CRYPT_INVALID_ARG; | |
90 | } | |
91 | ||
92 | /* is there an accelerator? */ | |
93 | if (cipher_descriptor[cipher].accel_ccm_memory != NULL) { | |
94 | return cipher_descriptor[cipher].accel_ccm_memory( | |
95 | key, keylen, | |
96 | uskey, | |
97 | nonce, noncelen, | |
98 | header, headerlen, | |
99 | pt, ptlen, | |
100 | ct, | |
101 | tag, taglen, | |
102 | direction); | |
103 | } | |
104 | ||
105 | /* let's get the L value */ | |
106 | len = ptlen; | |
107 | L = 0; | |
108 | while (len) { | |
109 | ++L; | |
110 | len >>= 8; | |
111 | } | |
112 | if (L <= 1) { | |
113 | L = 2; | |
114 | } | |
115 | ||
116 | /* increase L to match the nonce len */ | |
117 | noncelen = (noncelen > 13) ? 13 : noncelen; | |
118 | if ((15 - noncelen) > L) { | |
119 | L = 15 - noncelen; | |
120 | } | |
121 | ||
122 | /* decrease noncelen to match L */ | |
123 | if ((noncelen + L) > 15) { | |
124 | noncelen = 15 - L; | |
125 | } | |
126 | ||
127 | /* allocate mem for the symmetric key */ | |
128 | if (uskey == NULL) { | |
129 | skey = XMALLOC(sizeof(*skey)); | |
130 | if (skey == NULL) { | |
131 | return CRYPT_MEM; | |
132 | } | |
133 | ||
134 | /* initialize the cipher */ | |
135 | if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, skey)) != CRYPT_OK) { | |
136 | XFREE(skey); | |
137 | return err; | |
138 | } | |
139 | } else { | |
140 | skey = uskey; | |
141 | } | |
142 | ||
143 | /* form B_0 == flags | Nonce N | l(m) */ | |
144 | x = 0; | |
145 | ||
146 | if (B_0 == NULL) { | |
147 | PAD[x++] = (unsigned char)(((headerlen > 0) ? (1<<6) : 0) | | |
148 | (((*taglen - 2)>>1)<<3) | | |
149 | (L-1)); | |
150 | ||
151 | /* nonce */ | |
152 | for (y = 0; y < (16 - (L + 1)); y++) { | |
153 | PAD[x++] = nonce[y]; | |
154 | } | |
155 | ||
156 | /* store len */ | |
157 | len = ptlen; | |
158 | ||
159 | /* shift len so the upper bytes of len are the contents of the length */ | |
160 | for (y = L; y < 4; y++) { | |
161 | len <<= 8; | |
162 | } | |
163 | ||
164 | /* store l(m) (only store 32-bits) */ | |
165 | for (y = 0; L > 4 && (L-y)>4; y++) { | |
166 | PAD[x++] = 0; | |
167 | } | |
168 | for (; y < L; y++) { | |
169 | PAD[x++] = (unsigned char)((len >> 24) & 255); | |
170 | len <<= 8; | |
171 | } | |
172 | ||
173 | } else { | |
174 | // B_0 != NULL | |
175 | XMEMCPY(PAD, B_0, 16); | |
176 | } | |
177 | ||
178 | /* encrypt PAD */ | |
179 | if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) { | |
180 | goto error; | |
181 | } | |
182 | ||
183 | /* handle header */ | |
184 | if (headerlen > 0) { | |
185 | x = 0; | |
186 | ||
187 | #if 0 | |
188 | /* store length */ | |
189 | if (headerlen < ((1UL<<16) - (1UL<<8))) { | |
190 | PAD[x++] ^= (headerlen>>8) & 255; | |
191 | PAD[x++] ^= headerlen & 255; | |
192 | } else { | |
193 | PAD[x++] ^= 0xFF; | |
194 | PAD[x++] ^= 0xFE; | |
195 | PAD[x++] ^= (headerlen>>24) & 255; | |
196 | PAD[x++] ^= (headerlen>>16) & 255; | |
197 | PAD[x++] ^= (headerlen>>8) & 255; | |
198 | PAD[x++] ^= headerlen & 255; | |
199 | } | |
200 | #endif | |
201 | ||
202 | /* now add the data */ | |
203 | for (y = 0; y < headerlen; y++) { | |
204 | if (x == 16) { | |
205 | /* full block so let's encrypt it */ | |
206 | if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) { | |
207 | goto error; | |
208 | } | |
209 | x = 0; | |
210 | } | |
211 | PAD[x++] ^= header[y]; | |
212 | } | |
213 | ||
214 | /* remainder? */ | |
215 | if (x != 0) { | |
216 | if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) { | |
217 | goto error; | |
218 | } | |
219 | } | |
220 | } | |
221 | ||
222 | /* setup the ctr counter */ | |
223 | if (CTR == NULL) { | |
224 | x = 0; | |
225 | ||
226 | /* flags */ | |
227 | ctr[x++] = (unsigned char)L-1; | |
228 | ||
229 | /* nonce */ | |
230 | for (y = 0; y < (16 - (L+1)); ++y) { | |
231 | ctr[x++] = nonce[y]; | |
232 | } | |
233 | /* offset */ | |
234 | while (x < 16) { | |
235 | ctr[x++] = 0; | |
236 | } | |
237 | } else { | |
238 | XMEMCPY(ctr, CTR, 16); | |
239 | } | |
240 | ||
241 | x = 0; | |
242 | CTRlen = 16; | |
243 | ||
244 | /* now handle the PT */ | |
245 | if (ptlen > 0) { | |
246 | y = 0; | |
247 | #ifdef LTC_FAST2 | |
248 | if (ptlen & ~15) { | |
249 | if (direction == CCM_ENCRYPT) { | |
250 | for (; y < (ptlen & ~15); y += 16) { | |
251 | /* increment the ctr? */ | |
252 | for (z = 15; (int)z > (int)(15-ctrwidth); z--) { | |
253 | ctr[z] = (ctr[z] + 1) & 255; | |
254 | if (ctr[z]) break; | |
255 | } | |
256 | if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) { | |
257 | goto error; | |
258 | } | |
259 | ||
260 | /* xor the PT against the pad first */ | |
261 | for (z = 0; z < 16; z += sizeof(LTC_FAST_TYPE)) { | |
262 | *(LTC_FAST_TYPE_PTR_CAST(&PAD[z])) ^= *(LTC_FAST_TYPE_PTR_CAST(&pt[y+z])); | |
263 | *(LTC_FAST_TYPE_PTR_CAST(&ct[y+z])) = *(LTC_FAST_TYPE_PTR_CAST(&pt[y+z])) ^ *(LTC_FAST_TYPE_PTR_CAST(&CTRPAD[z])); | |
264 | } | |
265 | if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) { | |
266 | goto error; | |
267 | } | |
268 | } | |
269 | } else { | |
270 | for (; y < (ptlen & ~15); y += 16) { | |
271 | /* increment the ctr? */ | |
272 | for (z = 15; (int)z > (int)(15-ctrwidth); z--) { | |
273 | ctr[z] = (ctr[z] + 1) & 255; | |
274 | if (ctr[z]) break; | |
275 | } | |
276 | if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) { | |
277 | goto error; | |
278 | } | |
279 | ||
280 | /* xor the PT against the pad last */ | |
281 | for (z = 0; z < 16; z += sizeof(LTC_FAST_TYPE)) { | |
282 | *(LTC_FAST_TYPE_PTR_CAST(&pt[y+z])) = *(LTC_FAST_TYPE_PTR_CAST(&ct[y+z])) ^ *(LTC_FAST_TYPE_PTR_CAST(&CTRPAD[z])); | |
283 | *(LTC_FAST_TYPE_PTR_CAST(&PAD[z])) ^= *(LTC_FAST_TYPE_PTR_CAST(&pt[y+z])); | |
284 | } | |
285 | if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) { | |
286 | goto error; | |
287 | } | |
288 | } | |
289 | } | |
290 | } | |
291 | #endif | |
292 | ||
293 | for (; y < ptlen; y++) { | |
294 | /* increment the ctr? */ | |
295 | if (CTRlen == 16) { | |
296 | for (z = 15; (int)z > (int)(15-ctrwidth); z--) { | |
297 | ctr[z] = (ctr[z] + 1) & 255; | |
298 | if (ctr[z]) break; | |
299 | } | |
300 | if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) { | |
301 | goto error; | |
302 | } | |
303 | CTRlen = 0; | |
304 | } | |
305 | ||
306 | /* if we encrypt we add the bytes to the MAC first */ | |
307 | if (direction == CCM_ENCRYPT) { | |
308 | b = pt[y]; | |
309 | ct[y] = b ^ CTRPAD[CTRlen++]; | |
310 | } else { | |
311 | b = ct[y] ^ CTRPAD[CTRlen++]; | |
312 | pt[y] = b; | |
313 | } | |
314 | ||
315 | if (x == 16) { | |
316 | if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) { | |
317 | goto error; | |
318 | } | |
319 | x = 0; | |
320 | } | |
321 | PAD[x++] ^= b; | |
322 | } | |
323 | ||
324 | if (x != 0) { | |
325 | if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) { | |
326 | goto error; | |
327 | } | |
328 | } | |
329 | } | |
330 | ||
331 | // grab the CTR | |
332 | XMEMCPY(ctrcopy, ctr, 16); | |
333 | ||
334 | /* setup CTR for the TAG (zero the count) */ | |
335 | if (CTR == NULL) { | |
336 | for (y = 15; y > 15 - L; y--) { | |
337 | ctr[y] = 0x00; | |
338 | } | |
339 | } else { | |
340 | XMEMCPY(ctr, CTR, 16); | |
341 | } | |
342 | ||
343 | if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) { | |
344 | goto error; | |
345 | } | |
346 | ||
347 | if (skey != uskey) { | |
348 | cipher_descriptor[cipher].done(skey); | |
349 | } | |
350 | ||
351 | /* store the TAG */ | |
352 | for (x = 0; x < 16 && x < *taglen; x++) { | |
353 | tag[x] = PAD[x] ^ CTRPAD[x]; | |
354 | } | |
355 | *taglen = x; | |
356 | ||
357 | if (CTR != NULL) { | |
358 | for (z = 15; (int)z > (int)(15-ctrwidth); z--) { | |
359 | ctrcopy[z] = (ctrcopy[z] + 1) & 255; | |
360 | if (ctrcopy[z]) break; | |
361 | } | |
362 | memcpy(CTR, ctrcopy, 16); | |
363 | } | |
364 | ||
365 | #ifdef LTC_CLEAN_STACK | |
366 | zeromem(skey, sizeof(*skey)); | |
367 | zeromem(PAD, sizeof(PAD)); | |
368 | zeromem(CTRPAD, sizeof(CTRPAD)); | |
369 | #endif | |
370 | error: | |
371 | if (skey != uskey) { | |
372 | XFREE(skey); | |
373 | } | |
374 | ||
375 | return err; | |
376 | } | |
377 | ||
378 | #endif | |
379 | ||
380 | /* $Source$ */ | |
381 | /* $Revision$ */ | |
382 | /* $Date$ */ |
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 | ||
9 | #include "tomcrypt.h" | |
10 | ||
11 | #ifdef LTC_CHACHA20POLY1305_MODE | |
12 | ||
13 | /** | |
14 | Add AAD to the ChaCha20Poly1305 state | |
15 | @param st The ChaCha20Poly1305 state | |
16 | @param in The additional authentication data to add to the ChaCha20Poly1305 state | |
17 | @param inlen The length of the ChaCha20Poly1305 data. | |
18 | @return CRYPT_OK on success | |
19 | */ | |
20 | int chacha20poly1305_add_aad(chacha20poly1305_state *st, const unsigned char *in, unsigned long inlen) | |
21 | { | |
22 | int err; | |
23 | ||
24 | if (inlen == 0) return CRYPT_OK; /* nothing to do */ | |
25 | LTC_ARGCHK(st != NULL); | |
26 | ||
27 | if (st->aadflg == 0) return CRYPT_ERROR; | |
28 | if ((err = poly1305_process(&st->poly, in, inlen)) != CRYPT_OK) return err; | |
29 | st->aadlen += (ulong64)inlen; | |
30 | return CRYPT_OK; | |
31 | } | |
32 | ||
33 | #endif |
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 | ||
9 | #include "tomcrypt.h" | |
10 | ||
11 | #ifdef LTC_CHACHA20POLY1305_MODE | |
12 | ||
13 | /** | |
14 | Decrypt bytes of ciphertext with ChaCha20Poly1305 | |
15 | @param st The ChaCha20Poly1305 state | |
16 | @param in The ciphertext | |
17 | @param inlen The length of the input (octets) | |
18 | @param out [out] The plaintext (length inlen) | |
19 | @return CRYPT_OK if successful | |
20 | */ | |
21 | int chacha20poly1305_decrypt(chacha20poly1305_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out) | |
22 | { | |
23 | unsigned char padzero[16] = { 0 }; | |
24 | unsigned long padlen; | |
25 | int err; | |
26 | ||
27 | if (inlen == 0) return CRYPT_OK; /* nothing to do */ | |
28 | LTC_ARGCHK(st != NULL); | |
29 | ||
30 | if (st->aadflg) { | |
31 | padlen = 16 - (st->aadlen % 16); | |
32 | if (padlen < 16) { | |
33 | if ((err = poly1305_process(&st->poly, padzero, padlen)) != CRYPT_OK) return err; | |
34 | } | |
35 | st->aadflg = 0; /* no more AAD */ | |
36 | } | |
37 | if (st->aadflg) st->aadflg = 0; /* no more AAD */ | |
38 | if ((err = poly1305_process(&st->poly, in, inlen)) != CRYPT_OK) return err; | |
39 | if ((err = chacha_crypt(&st->chacha, in, inlen, out)) != CRYPT_OK) return err; | |
40 | st->ctlen += (ulong64)inlen; | |
41 | return CRYPT_OK; | |
42 | } | |
43 | ||
44 | #endif |
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 | ||
9 | #include "tomcrypt.h" | |
10 | ||
11 | #ifdef LTC_CHACHA20POLY1305_MODE | |
12 | ||
13 | /** | |
14 | Terminate a ChaCha20Poly1305 stream | |
15 | @param st The ChaCha20Poly1305 state | |
16 | @param tag [out] The destination for the MAC tag | |
17 | @param taglen [in/out] The length of the MAC tag | |
18 | @return CRYPT_OK on success | |
19 | */ | |
20 | int chacha20poly1305_done(chacha20poly1305_state *st, unsigned char *tag, unsigned long *taglen) | |
21 | { | |
22 | unsigned char padzero[16] = { 0 }; | |
23 | unsigned long padlen; | |
24 | unsigned char buf[16]; | |
25 | int err; | |
26 | ||
27 | LTC_ARGCHK(st != NULL); | |
28 | ||
29 | padlen = 16 - (st->ctlen % 16); | |
30 | if (padlen < 16) { | |
31 | if ((err = poly1305_process(&st->poly, padzero, padlen)) != CRYPT_OK) return err; | |
32 | } | |
33 | STORE64L(st->aadlen, buf); | |
34 | STORE64L(st->ctlen, buf + 8); | |
35 | if ((err = poly1305_process(&st->poly, buf, 16)) != CRYPT_OK) return err; | |
36 | if ((err = poly1305_done(&st->poly, tag, taglen)) != CRYPT_OK) return err; | |
37 | if ((err = chacha_done(&st->chacha)) != CRYPT_OK) return err; | |
38 | return CRYPT_OK; | |
39 | } | |
40 | ||
41 | #endif |
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 | ||
9 | #include "tomcrypt.h" | |
10 | ||
11 | #ifdef LTC_CHACHA20POLY1305_MODE | |
12 | ||
13 | /** | |
14 | Encrypt bytes of ciphertext with ChaCha20Poly1305 | |
15 | @param st The ChaCha20Poly1305 state | |
16 | @param in The plaintext | |
17 | @param inlen The length of the input (octets) | |
18 | @param out [out] The ciphertext (length inlen) | |
19 | @return CRYPT_OK if successful | |
20 | */ | |
21 | int chacha20poly1305_encrypt(chacha20poly1305_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out) | |
22 | { | |
23 | unsigned char padzero[16] = { 0 }; | |
24 | unsigned long padlen; | |
25 | int err; | |
26 | ||
27 | if (inlen == 0) return CRYPT_OK; /* nothing to do */ | |
28 | LTC_ARGCHK(st != NULL); | |
29 | ||
30 | if ((err = chacha_crypt(&st->chacha, in, inlen, out)) != CRYPT_OK) return err; | |
31 | if (st->aadflg) { | |
32 | padlen = 16 - (st->aadlen % 16); | |
33 | if (padlen < 16) { | |
34 | if ((err = poly1305_process(&st->poly, padzero, padlen)) != CRYPT_OK) return err; | |
35 | } | |
36 | st->aadflg = 0; /* no more AAD */ | |
37 | } | |
38 | if ((err = poly1305_process(&st->poly, out, inlen)) != CRYPT_OK) return err; | |
39 | st->ctlen += (ulong64)inlen; | |
40 | return CRYPT_OK; | |
41 | } | |
42 | ||
43 | #endif |
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 | ||
9 | #include "tomcrypt.h" | |
10 | ||
11 | #ifdef LTC_CHACHA20POLY1305_MODE | |
12 | ||
13 | /** | |
14 | Initialize an ChaCha20Poly1305 context (only the key) | |
15 | @param st [out] The destination of the ChaCha20Poly1305 state | |
16 | @param key The secret key | |
17 | @param keylen The length of the secret key (octets) | |
18 | @return CRYPT_OK if successful | |
19 | */ | |
20 | int chacha20poly1305_init(chacha20poly1305_state *st, const unsigned char *key, unsigned long keylen) | |
21 | { | |
22 | return chacha_setup(&st->chacha, key, keylen, 20); | |
23 | } | |
24 | ||
25 | #endif |
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 | ||
9 | #include "tomcrypt.h" | |
10 | ||
11 | #ifdef LTC_CHACHA20POLY1305_MODE | |
12 | ||
13 | /** | |
14 | Process an entire GCM packet in one call. | |
15 | @param key The secret key | |
16 | @param keylen The length of the secret key | |
17 | @param iv The initial vector | |
18 | @param ivlen The length of the initial vector | |
19 | @param aad The additional authentication data (header) | |
20 | @param aadlen The length of the aad | |
21 | @param in The plaintext | |
22 | @param inlen The length of the plaintext (ciphertext length is the same) | |
23 | @param out The ciphertext | |
24 | @param tag [out] The MAC tag | |
25 | @param taglen [in/out] The MAC tag length | |
26 | @param direction Encrypt or Decrypt mode (CHCHA20POLY1305_ENCRYPT or CHCHA20POLY1305_DECRYPT) | |
27 | @return CRYPT_OK on success | |
28 | */ | |
29 | int chacha20poly1305_memory(const unsigned char *key, unsigned long keylen, | |
30 | const unsigned char *iv, unsigned long ivlen, | |
31 | const unsigned char *aad, unsigned long aadlen, | |
32 | const unsigned char *in, unsigned long inlen, | |
33 | unsigned char *out, | |
34 | unsigned char *tag, unsigned long *taglen, | |
35 | int direction) | |
36 | { | |
37 | chacha20poly1305_state st; | |
38 | int err; | |
39 | ||
40 | LTC_ARGCHK(key != NULL); | |
41 | LTC_ARGCHK(iv != NULL); | |
42 | LTC_ARGCHK(in != NULL); | |
43 | LTC_ARGCHK(out != NULL); | |
44 | LTC_ARGCHK(tag != NULL); | |
45 | ||
46 | if ((err = chacha20poly1305_init(&st, key, keylen)) != CRYPT_OK) { goto LBL_ERR; } | |
47 | if ((err = chacha20poly1305_setiv(&st, iv, ivlen)) != CRYPT_OK) { goto LBL_ERR; } | |
48 | if (aad && aadlen > 0) { | |
49 | if ((err = chacha20poly1305_add_aad(&st, aad, aadlen)) != CRYPT_OK) { goto LBL_ERR; } | |
50 | } | |
51 | if (direction == CHCHA20POLY1305_ENCRYPT) { | |
52 | if ((err = chacha20poly1305_encrypt(&st, in, inlen, out)) != CRYPT_OK) { goto LBL_ERR; } | |
53 | } | |
54 | else if (direction == CHCHA20POLY1305_DECRYPT) { | |
55 | if ((err = chacha20poly1305_decrypt(&st, in, inlen, out)) != CRYPT_OK) { goto LBL_ERR; } | |
56 | } | |
57 | else { | |
58 | err = CRYPT_INVALID_ARG; | |
59 | goto LBL_ERR; | |
60 | } | |
61 | err = chacha20poly1305_done(&st, tag, taglen); | |
62 | LBL_ERR: | |
63 | #ifdef LTC_CLEAN_STACK | |
64 | zeromem(&st, sizeof(chacha20poly1305_state)); | |
65 | #endif | |
66 | return err; | |
67 | } | |
68 | ||
69 | #endif |
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 | ||
9 | #include "tomcrypt.h" | |
10 | ||
11 | #ifdef LTC_CHACHA20POLY1305_MODE | |
12 | ||
13 | /** | |
14 | Set IV + counter data to the ChaCha20Poly1305 state and reset the context | |
15 | @param st The ChaCha20Poly1305 state | |
16 | @param iv The IV data to add | |
17 | @param inlen The length of the IV (must be 12 or 8) | |
18 | @return CRYPT_OK on success | |
19 | */ | |
20 | int chacha20poly1305_setiv(chacha20poly1305_state *st, const unsigned char *iv, unsigned long ivlen) | |
21 | { | |
22 | chacha_state tmp_st; | |
23 | int i, err; | |
24 | unsigned char polykey[32]; | |
25 | ||
26 | LTC_ARGCHK(st != NULL); | |
27 | LTC_ARGCHK(iv != NULL); | |
28 | LTC_ARGCHK(ivlen == 12 || ivlen == 8); | |
29 | ||
30 | /* set IV for chacha20 */ | |
31 | if (ivlen == 12) { | |
32 | /* IV 96bit */ | |
33 | if ((err = chacha_ivctr32(&st->chacha, iv, ivlen, 1)) != CRYPT_OK) return err; | |
34 | } | |
35 | else { | |
36 | /* IV 64bit */ | |
37 | if ((err = chacha_ivctr64(&st->chacha, iv, ivlen, 1)) != CRYPT_OK) return err; | |
38 | } | |
39 | ||
40 | /* copy chacha20 key to temporary state */ | |
41 | for(i = 0; i < 12; i++) tmp_st.input[i] = st->chacha.input[i]; | |
42 | tmp_st.rounds = 20; | |
43 | /* set IV */ | |
44 | if (ivlen == 12) { | |
45 | /* IV 32bit */ | |
46 | if ((err = chacha_ivctr32(&tmp_st, iv, ivlen, 0)) != CRYPT_OK) return err; | |
47 | } | |
48 | else { | |
49 | /* IV 64bit */ | |
50 | if ((err = chacha_ivctr64(&tmp_st, iv, ivlen, 0)) != CRYPT_OK) return err; | |
51 | } | |
52 | /* (re)generate new poly1305 key */ | |
53 | if ((err = chacha_keystream(&tmp_st, polykey, 32)) != CRYPT_OK) return err; | |
54 | /* (re)initialise poly1305 */ | |
55 | if ((err = poly1305_init(&st->poly, polykey, 32)) != CRYPT_OK) return err; | |
56 | st->ctlen = 0; | |
57 | st->aadlen = 0; | |
58 | st->aadflg = 1; | |
59 | ||
60 | return CRYPT_OK; | |
61 | } | |
62 | ||
63 | #endif |
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 | ||
9 | #include "tomcrypt.h" | |
10 | ||
11 | #ifdef LTC_CHACHA20POLY1305_MODE | |
12 | ||
13 | /** | |
14 | Set IV + counter data (with RFC7905-magic) to the ChaCha20Poly1305 state and reset the context | |
15 | @param st The ChaCha20Poly1305 state | |
16 | @param iv The IV data to add | |
17 | @param inlen The length of the IV (must be 12 or 8) | |
18 | @param sequence_number 64bit sequence number which is incorporated into IV as described in RFC7905 | |
19 | @return CRYPT_OK on success | |
20 | */ | |
21 | int chacha20poly1305_setiv_rfc7905(chacha20poly1305_state *st, const unsigned char *iv, unsigned long ivlen, ulong64 sequence_number) | |
22 | { | |
23 | int i; | |
24 | unsigned char combined_iv[12] = { 0 }; | |
25 | ||
26 | LTC_ARGCHK(st != NULL); | |
27 | LTC_ARGCHK(iv != NULL); | |
28 | LTC_ARGCHK(ivlen == 12); | |
29 | ||
30 | STORE64L(sequence_number, combined_iv + 4); | |
31 | for (i = 0; i < 12; i++) combined_iv[i] = iv[i] ^ combined_iv[i]; | |
32 | return chacha20poly1305_setiv(st, combined_iv, 12); | |
33 | } | |
34 | ||
35 | #endif |
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 | ||
9 | /* based on https://github.com/brainhub/SHA3IUF (public domain) */ | |
10 | ||
11 | #include "tomcrypt.h" | |
12 | ||
13 | #ifdef LTC_SHA3 | |
14 | ||
15 | const struct ltc_hash_descriptor sha3_224_desc = | |
16 | { | |
17 | "sha3_224", /* name of hash */ | |
18 | 17, /* internal ID */ | |
19 | 28, /* Size of digest in octets */ | |
20 | 128, /* Input block size in octets */ | |
21 | { 2,16,840,1,101,3,4,2,7 }, /* ASN.1 OID */ | |
22 | 9, /* Length OID */ | |
23 | &sha3_224_init, | |
24 | &sha3_process, | |
25 | &sha3_done, | |
26 | &sha3_224_test, | |
27 | NULL | |
28 | }; | |
29 | ||
30 | const struct ltc_hash_descriptor sha3_256_desc = | |
31 | { | |
32 | "sha3_256", /* name of hash */ | |
33 | 18, /* internal ID */ | |
34 | 32, /* Size of digest in octets */ | |
35 | 128, /* Input block size in octets */ | |
36 | { 2,16,840,1,101,3,4,2,8 }, /* ASN.1 OID */ | |
37 | 9, /* Length OID */ | |
38 | &sha3_256_init, | |
39 | &sha3_process, | |
40 | &sha3_done, | |
41 | &sha3_256_test, | |
42 | NULL | |
43 | }; | |
44 | ||
45 | const struct ltc_hash_descriptor sha3_384_desc = | |
46 | { | |
47 | "sha3_384", /* name of hash */ | |
48 | 19, /* internal ID */ | |
49 | 48, /* Size of digest in octets */ | |
50 | 128, /* Input block size in octets */ | |
51 | { 2,16,840,1,101,3,4,2,9 }, /* ASN.1 OID */ | |
52 | 9, /* Length OID */ | |
53 | &sha3_384_init, | |
54 | &sha3_process, | |
55 | &sha3_done, | |
56 | &sha3_384_test, | |
57 | NULL | |
58 | }; | |
59 | ||
60 | const struct ltc_hash_descriptor sha3_512_desc = | |
61 | { | |
62 | "sha3_512", /* name of hash */ | |
63 | 20, /* internal ID */ | |
64 | 64, /* Size of digest in octets */ | |
65 | 128, /* Input block size in octets */ | |
66 | { 2,16,840,1,101,3,4,2,10 }, /* ASN.1 OID */ | |
67 | 9, /* Length OID */ | |
68 | &sha3_512_init, | |
69 | &sha3_process, | |
70 | &sha3_done, | |
71 | &sha3_512_test, | |
72 | NULL | |
73 | }; | |
74 | ||
75 | #define SHA3_KECCAK_SPONGE_WORDS 25 /* 1600 bits > 200 bytes > 25 x ulong64 */ | |
76 | #define SHA3_KECCAK_ROUNDS 24 | |
77 | ||
78 | static const ulong64 keccakf_rndc[24] = { | |
79 | CONST64(0x0000000000000001), CONST64(0x0000000000008082), | |
80 | CONST64(0x800000000000808a), CONST64(0x8000000080008000), | |
81 | CONST64(0x000000000000808b), CONST64(0x0000000080000001), | |
82 | CONST64(0x8000000080008081), CONST64(0x8000000000008009), | |
83 | CONST64(0x000000000000008a), CONST64(0x0000000000000088), | |
84 | CONST64(0x0000000080008009), CONST64(0x000000008000000a), | |
85 | CONST64(0x000000008000808b), CONST64(0x800000000000008b), | |
86 | CONST64(0x8000000000008089), CONST64(0x8000000000008003), | |
87 | CONST64(0x8000000000008002), CONST64(0x8000000000000080), | |
88 | CONST64(0x000000000000800a), CONST64(0x800000008000000a), | |
89 | CONST64(0x8000000080008081), CONST64(0x8000000000008080), | |
90 | CONST64(0x0000000080000001), CONST64(0x8000000080008008) | |
91 | }; | |
92 | ||
93 | static const unsigned keccakf_rotc[24] = { | |
94 | 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44 | |
95 | }; | |
96 | ||
97 | static const unsigned keccakf_piln[24] = { | |
98 | 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1 | |
99 | }; | |
100 | ||
101 | static void keccakf(ulong64 s[25]) | |
102 | { | |
103 | int i, j, round; | |
104 | ulong64 t, bc[5]; | |
105 | ||
106 | for(round = 0; round < SHA3_KECCAK_ROUNDS; round++) { | |
107 | /* Theta */ | |
108 | for(i = 0; i < 5; i++) | |
109 | bc[i] = s[i] ^ s[i + 5] ^ s[i + 10] ^ s[i + 15] ^ s[i + 20]; | |
110 | ||
111 | for(i = 0; i < 5; i++) { | |
112 | t = bc[(i + 4) % 5] ^ ROL64(bc[(i + 1) % 5], 1); | |
113 | for(j = 0; j < 25; j += 5) | |
114 | s[j + i] ^= t; | |
115 | } | |
116 | /* Rho Pi */ | |
117 | t = s[1]; | |
118 | for(i = 0; i < 24; i++) { | |
119 | j = keccakf_piln[i]; | |
120 | bc[0] = s[j]; | |
121 | s[j] = ROL64(t, keccakf_rotc[i]); | |
122 | t = bc[0]; | |
123 | } | |
124 | /* Chi */ | |
125 | for(j = 0; j < 25; j += 5) { | |
126 | for(i = 0; i < 5; i++) | |
127 | bc[i] = s[j + i]; | |
128 | for(i = 0; i < 5; i++) | |
129 | s[j + i] ^= (~bc[(i + 1) % 5]) & bc[(i + 2) % 5]; | |
130 | } | |
131 | /* Iota */ | |
132 | s[0] ^= keccakf_rndc[round]; | |
133 | } | |
134 | } | |
135 | ||
136 | /* Public Inteface */ | |
137 | ||
138 | int sha3_224_init(hash_state *md) | |
139 | { | |
140 | LTC_ARGCHK(md != NULL); | |
141 | XMEMSET(&md->sha3, 0, sizeof(md->sha3)); | |
142 | md->sha3.capacity_words = 2 * 224 / (8 * sizeof(ulong64)); | |
143 | return CRYPT_OK; | |
144 | } | |
145 | ||
146 | int sha3_256_init(hash_state *md) | |
147 | { | |
148 | LTC_ARGCHK(md != NULL); | |
149 | XMEMSET(&md->sha3, 0, sizeof(md->sha3)); | |
150 | md->sha3.capacity_words = 2 * 256 / (8 * sizeof(ulong64)); | |
151 | return CRYPT_OK; | |
152 | } | |
153 | ||
154 | int sha3_384_init(hash_state *md) | |
155 | { | |
156 | LTC_ARGCHK(md != NULL); | |
157 | XMEMSET(&md->sha3, 0, sizeof(md->sha3)); | |
158 | md->sha3.capacity_words = 2 * 384 / (8 * sizeof(ulong64)); | |
159 | return CRYPT_OK; | |
160 | } | |
161 | ||
162 | int sha3_512_init(hash_state *md) | |
163 | { | |
164 | LTC_ARGCHK(md != NULL); | |
165 | XMEMSET(&md->sha3, 0, sizeof(md->sha3)); | |
166 | md->sha3.capacity_words = 2 * 512 / (8 * sizeof(ulong64)); | |
167 | return CRYPT_OK; | |
168 | } | |
169 | ||
170 | int sha3_shake_init(hash_state *md, int num) | |
171 | { | |
172 | LTC_ARGCHK(md != NULL); | |
173 | if (num != 128 && num != 256) return CRYPT_INVALID_ARG; | |
174 | XMEMSET(&md->sha3, 0, sizeof(md->sha3)); | |
175 | md->sha3.capacity_words = (unsigned short)(2 * num / (8 * sizeof(ulong64))); | |
176 | return CRYPT_OK; | |
177 | } | |
178 | ||
179 | int sha3_process(hash_state *md, const unsigned char *in, unsigned long inlen) | |
180 | { | |
181 | /* 0...7 -- how much is needed to have a word */ | |
182 | unsigned old_tail = (8 - md->sha3.byte_index) & 7; | |
183 | ||
184 | unsigned long words; | |
185 | unsigned tail; | |
186 | unsigned long i; | |
187 | ||
188 | if (inlen == 0) return CRYPT_OK; /* nothing to do */ | |
189 | LTC_ARGCHK(md != NULL); | |
190 | LTC_ARGCHK(in != NULL); | |
191 | ||
192 | if(inlen < old_tail) { /* have no complete word or haven't started the word yet */ | |
193 | while (inlen--) md->sha3.saved |= (ulong64) (*(in++)) << ((md->sha3.byte_index++) * 8); | |
194 | return CRYPT_OK; | |
195 | } | |
196 | ||
197 | if(old_tail) { /* will have one word to process */ | |
198 | inlen -= old_tail; | |
199 | while (old_tail--) md->sha3.saved |= (ulong64) (*(in++)) << ((md->sha3.byte_index++) * 8); | |
200 | /* now ready to add saved to the sponge */ | |
201 | md->sha3.s[md->sha3.word_index] ^= md->sha3.saved; | |
202 | md->sha3.byte_index = 0; | |
203 | md->sha3.saved = 0; | |
204 | if(++md->sha3.word_index == (SHA3_KECCAK_SPONGE_WORDS - md->sha3.capacity_words)) { | |
205 | keccakf(md->sha3.s); | |
206 | md->sha3.word_index = 0; | |
207 | } | |
208 | } | |
209 | ||
210 | /* now work in full words directly from input */ | |
211 | words = inlen / sizeof(ulong64); | |
212 | tail = inlen - words * sizeof(ulong64); | |
213 | ||
214 | for(i = 0; i < words; i++, in += sizeof(ulong64)) { | |
215 | ulong64 t; | |
216 | LOAD64L(t, in); | |
217 | md->sha3.s[md->sha3.word_index] ^= t; | |
218 | if(++md->sha3.word_index == (SHA3_KECCAK_SPONGE_WORDS - md->sha3.capacity_words)) { | |
219 | keccakf(md->sha3.s); | |
220 | md->sha3.word_index = 0; | |
221 | } | |
222 | } | |
223 | ||
224 | /* finally, save the partial word */ | |
225 | while (tail--) { | |
226 | md->sha3.saved |= (ulong64) (*(in++)) << ((md->sha3.byte_index++) * 8); | |
227 | } | |
228 | return CRYPT_OK; | |
229 | } | |
230 | ||
231 | int sha3_done(hash_state *md, unsigned char *hash) | |
232 | { | |
233 | LTC_ARGCHK(md != NULL); | |
234 | LTC_ARGCHK(hash != NULL); | |
235 | ||
236 | md->sha3.s[md->sha3.word_index] ^= (md->sha3.saved ^ (CONST64(0x06) << (md->sha3.byte_index * 8))); | |
237 | md->sha3.s[SHA3_KECCAK_SPONGE_WORDS - md->sha3.capacity_words - 1] ^= CONST64(0x8000000000000000); | |
238 | keccakf(md->sha3.s); | |
239 | ||
240 | #ifndef ENDIAN_LITTLE | |
241 | { | |
242 | unsigned i; | |
243 | for(i = 0; i < SHA3_KECCAK_SPONGE_WORDS; i++) { | |
244 | const ulong32 t1 = (ulong32)(md->sha3.s[i] & CONST64(0xFFFFFFFF)); | |
245 | const ulong32 t2 = (ulong32)(md->sha3.s[i] >> 32); | |
246 | STORE32L(t1, md->sha3.sb + i * 8); | |
247 | STORE32L(t2, md->sha3.sb + i * 8 + 4); | |
248 | } | |
249 | } | |
250 | #endif | |
251 | ||
252 | XMEMCPY(hash, md->sha3.sb, md->sha3.capacity_words * 4); | |
253 | return CRYPT_OK; | |
254 | } | |
255 | ||
256 | int sha3_shake_done(hash_state *md, unsigned char *out, unsigned long outlen) | |
257 | { | |
258 | unsigned long i = 0; | |
259 | /* sha3_shake_done can be called many times */ | |
260 | ||
261 | if (outlen == 0) return CRYPT_OK; /* nothing to do */ | |
262 | LTC_ARGCHK(md != NULL); | |
263 | LTC_ARGCHK(out != NULL); | |
264 | ||
265 | if (!md->sha3.xof_flag) { | |
266 | /* shake_xof operation must be done only once */ | |
267 | md->sha3.s[md->sha3.word_index] ^= (md->sha3.saved ^ (CONST64(0x1F) << (md->sha3.byte_index * 8))); | |
268 | md->sha3.s[SHA3_KECCAK_SPONGE_WORDS - md->sha3.capacity_words - 1] ^= CONST64(0x8000000000000000); | |
269 | keccakf(md->sha3.s); | |
270 | md->sha3.byte_index = 0; | |
271 | md->sha3.xof_flag = 1; | |
272 | } | |
273 | ||
274 | while (i < outlen) { | |
275 | if(md->sha3.byte_index >= (SHA3_KECCAK_SPONGE_WORDS - md->sha3.capacity_words) * 8) { | |
276 | keccakf(md->sha3.s); | |
277 | md->sha3.byte_index = 0; | |
278 | } | |
279 | out[i++] = md->sha3.sb[md->sha3.byte_index++]; | |
280 | } | |
281 | return CRYPT_OK; | |
282 | } | |
283 | ||
284 | int sha3_shake_memory(int num, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen) | |
285 | { | |
286 | hash_state md; | |
287 | int err; | |
288 | LTC_ARGCHK(in != NULL); | |
289 | LTC_ARGCHK(out != NULL); | |
290 | LTC_ARGCHK(outlen != NULL); | |
291 | if ((err = sha3_shake_init(&md, num)) != CRYPT_OK) return err; | |
292 | if ((err = sha3_shake_process(&md, in, inlen)) != CRYPT_OK) return err; | |
293 | if ((err = sha3_shake_done(&md, out, *outlen)) != CRYPT_OK) return err; | |
294 | return CRYPT_OK; | |
295 | } | |
296 | ||
297 | #endif |
54 | 54 | CRYPT_FILE_NOTFOUND, /* File Not Found */ |
55 | 55 | |
56 | 56 | CRYPT_PK_INVALID_TYPE, /* Invalid type of PK key */ |
57 | CRYPT_PK_INVALID_SYSTEM,/* Invalid PK system specified */ | |
58 | CRYPT_PK_DUP, /* Duplicate key already in key ring */ | |
59 | CRYPT_PK_NOT_FOUND, /* Key not found in keyring */ | |
57 | ||
58 | CRYPT_OVERFLOW, /* An overflow of a value was detected/prevented */ | |
59 | ||
60 | CRYPT_UNUSED1, /* UNUSED1 */ | |
61 | CRYPT_UNUSED2, /* UNUSED2 */ | |
62 | ||
60 | 63 | CRYPT_PK_INVALID_SIZE, /* Invalid size input for PK parameters */ |
61 | 64 | |
62 | 65 | CRYPT_INVALID_PRIME_SIZE,/* Invalid size of prime requested */ |
936 | 936 | |
937 | 937 | LTC_MUTEX_PROTO(ltc_cipher_mutex) |
938 | 938 | |
939 | /* ---- stream ciphers ---- */ | |
940 | ||
941 | #ifdef LTC_CHACHA | |
942 | ||
943 | typedef struct { | |
944 | ulong32 input[16]; | |
945 | unsigned char kstream[64]; | |
946 | unsigned long ksleft; | |
947 | unsigned long ivlen; | |
948 | int rounds; | |
949 | } chacha_state; | |
950 | ||
951 | int chacha_setup(chacha_state *st, const unsigned char *key, unsigned long keylen, int rounds); | |
952 | int chacha_ivctr32(chacha_state *st, const unsigned char *iv, unsigned long ivlen, ulong32 counter); | |
953 | int chacha_ivctr64(chacha_state *st, const unsigned char *iv, unsigned long ivlen, ulong64 counter); | |
954 | int chacha_crypt(chacha_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out); | |
955 | int chacha_keystream(chacha_state *st, unsigned char *out, unsigned long outlen); | |
956 | int chacha_done(chacha_state *st); | |
957 | int chacha_test(void); | |
958 | ||
959 | #endif /* LTC_CHACHA */ | |
960 | ||
961 | #ifdef LTC_RC4 | |
962 | ||
963 | typedef struct { | |
964 | int x, y; | |
965 | unsigned char buf[256]; | |
966 | } rc4_state; | |
967 | ||
968 | int rc4_setup(rc4_state *st, const unsigned char *key, unsigned long keylen); | |
969 | int rc4_crypt(rc4_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out); | |
970 | int rc4_keystream(rc4_state *st, unsigned char *out, unsigned long outlen); | |
971 | int rc4_done(rc4_state *st); | |
972 | int rc4_test(void); | |
973 | ||
974 | #endif /* LTC_RC4 */ | |
975 | ||
976 | #ifdef LTC_SOBER128 | |
977 | ||
978 | typedef struct { | |
979 | ulong32 R[17], /* Working storage for the shift register */ | |
980 | initR[17], /* saved register contents */ | |
981 | konst, /* key dependent constant */ | |
982 | sbuf; /* partial word encryption buffer */ | |
983 | int nbuf; /* number of part-word stream bits buffered */ | |
984 | } sober128_state; | |
985 | ||
986 | int sober128_setup(sober128_state *st, const unsigned char *key, unsigned long keylen); | |
987 | int sober128_setiv(sober128_state *st, const unsigned char *iv, unsigned long ivlen); | |
988 | int sober128_crypt(sober128_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out); | |
989 | int sober128_keystream(sober128_state *st, unsigned char *out, unsigned long outlen); | |
990 | int sober128_done(sober128_state *st); | |
991 | int sober128_test(void); | |
992 | ||
993 | #endif /* LTC_SOBER128 */ | |
994 | ||
939 | 995 | /* $Source$ */ |
940 | 996 | /* $Revision$ */ |
941 | 997 | /* $Date$ */ |
22 | 22 | #endif |
23 | 23 | #ifndef XMEMCMP |
24 | 24 | #define XMEMCMP memcmp |
25 | #endif | |
26 | #ifndef XMEMMOVE | |
27 | #define XMEMMOVE memmove | |
25 | 28 | #endif |
26 | 29 | #ifndef XMEM_NEQ |
27 | 30 | #define XMEM_NEQ mem_neq |
73 | 76 | |
74 | 77 | #define LTC_NO_HASHES |
75 | 78 | #define LTC_SHA1 |
79 | #define LTC_SHA3 | |
76 | 80 | #define LTC_SHA512 |
77 | 81 | #define LTC_SHA384 |
78 | 82 | #define LTC_SHA256 |
187 | 191 | #define LTC_KASUMI |
188 | 192 | #define LTC_MULTI2 |
189 | 193 | #define LTC_CAMELLIA |
194 | /* ChaCha is special (a stream cipher) */ | |
195 | #define LTC_CHACHA | |
190 | 196 | |
191 | 197 | #endif /* LTC_NO_CIPHERS */ |
192 | 198 | |
222 | 228 | |
223 | 229 | #define LTC_CHC_HASH |
224 | 230 | #define LTC_WHIRLPOOL |
231 | #define LTC_SHA3 | |
225 | 232 | #define LTC_SHA512 |
226 | 233 | #define LTC_SHA512_256 |
227 | 234 | #define LTC_SHA512_224 |
252 | 259 | #define LTC_XCBC |
253 | 260 | #define LTC_F9_MODE |
254 | 261 | #define LTC_PELICAN |
262 | #define LTC_POLY1305 | |
255 | 263 | |
256 | 264 | /* ---> Encrypt + Authenticate Modes <--- */ |
257 | 265 | |
261 | 269 | #define LTC_OCB3_MODE |
262 | 270 | #define LTC_CCM_MODE |
263 | 271 | #define LTC_GCM_MODE |
272 | #define LTC_CHACHA20POLY1305_MODE | |
264 | 273 | |
265 | 274 | /* Use 64KiB tables */ |
266 | 275 | #ifndef LTC_NO_TABLES |
286 | 295 | |
287 | 296 | /* The LTC_RC4 stream cipher */ |
288 | 297 | #define LTC_RC4 |
298 | ||
299 | /* The ChaCha20 stream cipher based PRNG */ | |
300 | #define LTC_CHACHA20_PRNG | |
289 | 301 | |
290 | 302 | /* Fortuna PRNG */ |
291 | 303 | #define LTC_FORTUNA |
303 | 315 | /* rng_make_prng() */ |
304 | 316 | #define LTC_RNG_MAKE_PRNG |
305 | 317 | |
318 | /* enable the ltc_rng hook to integrate e.g. embedded hardware RNG's easily */ | |
319 | /* #define LTC_PRNG_ENABLE_LTC_RNG */ | |
320 | ||
306 | 321 | #endif /* LTC_NO_PRNGS */ |
307 | 322 | |
308 | 323 | #ifdef LTC_YARROW |
339 | 354 | #define LTC_MRSA |
340 | 355 | |
341 | 356 | /* Include Diffie-Hellman support */ |
342 | #ifndef GMP_DESC | |
343 | 357 | /* is_prime fails for GMP */ |
344 | 358 | #define LTC_MDH |
345 | 359 | /* Supported Key Sizes */ |
355 | 369 | #define LTC_DH2560 |
356 | 370 | #define LTC_DH3072 |
357 | 371 | #define LTC_DH4096 |
358 | #endif | |
359 | 372 | #endif |
360 | 373 | |
361 | 374 | /* Include Katja (a Rabin variant like RSA) */ |
528 | 541 | #error PK requires ASN.1 DER functionality, make sure LTC_DER is enabled |
529 | 542 | #endif |
530 | 543 | |
544 | #if defined(LTC_CHACHA20POLY1305_MODE) && (!defined(LTC_CHACHA) || !defined(LTC_POLY1305)) | |
545 | #error LTC_CHACHA20POLY1305_MODE requires LTC_CHACHA + LTC_POLY1305 | |
546 | #endif | |
547 | ||
548 | #if defined(LTC_CHACHA20_PRNG) && !defined(LTC_CHACHA) | |
549 | #error LTC_CHACHA20_PRNG requires LTC_CHACHA | |
550 | #endif | |
551 | ||
531 | 552 | /* THREAD management */ |
532 | 553 | #ifdef LTC_PTHREAD |
533 | 554 | |
559 | 580 | |
560 | 581 | #endif |
561 | 582 | |
562 | ||
583 | #ifndef LTC_NO_FILE | |
584 | /* buffer size for reading from a file via fread(..) */ | |
585 | #ifndef LTC_FILE_READ_BUFSIZE | |
586 | #define LTC_FILE_READ_BUFSIZE 8192 | |
587 | #endif | |
588 | #endif | |
563 | 589 | |
564 | 590 | /* $Source$ */ |
565 | 591 | /* $Revision$ */ |
0 | 0 | /* ---- HASH FUNCTIONS ---- */ |
1 | #ifdef LTC_SHA3 | |
2 | struct sha3_state { | |
3 | ulong64 saved; /* the portion of the input message that we didn't consume yet */ | |
4 | union { ulong64 s[25]; unsigned char sb[25 * 8]; }; | |
5 | unsigned short byte_index; /* 0..7--the next byte after the set one (starts from 0; 0--none are buffered) */ | |
6 | unsigned short word_index; /* 0..24--the next word to integrate input (starts from 0) */ | |
7 | unsigned short capacity_words; /* the double size of the hash output in words (e.g. 16 for Keccak 512) */ | |
8 | unsigned short xof_flag; | |
9 | }; | |
10 | #endif | |
11 | ||
1 | 12 | #ifdef LTC_SHA512 |
2 | 13 | struct sha512_state { |
3 | 14 | ulong64 length, state[8]; |
108 | 119 | #endif |
109 | 120 | #ifdef LTC_WHIRLPOOL |
110 | 121 | struct whirlpool_state whirlpool; |
122 | #endif | |
123 | #ifdef LTC_SHA3 | |
124 | struct sha3_state sha3; | |
111 | 125 | #endif |
112 | 126 | #ifdef LTC_SHA512 |
113 | 127 | struct sha512_state sha512; |
205 | 219 | int whirlpool_done(hash_state * md, unsigned char *hash); |
206 | 220 | int whirlpool_test(void); |
207 | 221 | extern const struct ltc_hash_descriptor whirlpool_desc; |
222 | #endif | |
223 | ||
224 | #ifdef LTC_SHA3 | |
225 | int sha3_512_init(hash_state * md); | |
226 | int sha3_512_test(void); | |
227 | extern const struct ltc_hash_descriptor sha3_512_desc; | |
228 | int sha3_384_init(hash_state * md); | |
229 | int sha3_384_test(void); | |
230 | extern const struct ltc_hash_descriptor sha3_384_desc; | |
231 | int sha3_256_init(hash_state * md); | |
232 | int sha3_256_test(void); | |
233 | extern const struct ltc_hash_descriptor sha3_256_desc; | |
234 | int sha3_224_init(hash_state * md); | |
235 | int sha3_224_test(void); | |
236 | extern const struct ltc_hash_descriptor sha3_224_desc; | |
237 | /* process + done are the same for all variants */ | |
238 | int sha3_process(hash_state * md, const unsigned char *in, unsigned long inlen); | |
239 | int sha3_done(hash_state *md, unsigned char *hash); | |
240 | /* SHAKE128 + SHAKE256 */ | |
241 | int sha3_shake_init(hash_state *md, int num); | |
242 | #define sha3_shake_process(a,b,c) sha3_process(a,b,c) | |
243 | int sha3_shake_done(hash_state *md, unsigned char *out, unsigned long outlen); | |
244 | int sha3_shake_test(void); | |
245 | int sha3_shake_memory(int num, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); | |
208 | 246 | #endif |
209 | 247 | |
210 | 248 | #ifdef LTC_SHA512 |
95 | 95 | |
96 | 96 | #endif /* PMAC */ |
97 | 97 | |
98 | #ifdef LTC_POLY1305 | |
99 | typedef struct { | |
100 | ulong32 r[5]; | |
101 | ulong32 h[5]; | |
102 | ulong32 pad[4]; | |
103 | unsigned long leftover; | |
104 | unsigned char buffer[16]; | |
105 | int final; | |
106 | } poly1305_state; | |
107 | ||
108 | int poly1305_init(poly1305_state *st, const unsigned char *key, unsigned long keylen); | |
109 | int poly1305_process(poly1305_state *st, const unsigned char *in, unsigned long inlen); | |
110 | int poly1305_done(poly1305_state *st, unsigned char *mac, unsigned long *maclen); | |
111 | int poly1305_test(void); | |
112 | int poly1305_memory(const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *mac, unsigned long *maclen); | |
113 | int poly1305_memory_multi(const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen, const unsigned char *in, unsigned long inlen, ...); | |
114 | int poly1305_file(const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen); | |
115 | int poly1305_test(void); | |
116 | #endif /* LTC_POLY1305 */ | |
117 | ||
98 | 118 | #ifdef LTC_EAX_MODE |
99 | 119 | |
100 | 120 | #if !(defined(LTC_OMAC) && defined(LTC_CTR_MODE)) |
305 | 325 | unsigned char *ct, |
306 | 326 | unsigned char *tag, unsigned long *taglen, |
307 | 327 | int direction); |
308 | ||
309 | int ccm_memory_ex(int cipher, | |
310 | const unsigned char *key, unsigned long keylen, | |
311 | symmetric_key *uskey, | |
312 | const unsigned char *nonce, unsigned long noncelen, | |
313 | const unsigned char *header, unsigned long headerlen, | |
314 | unsigned char *pt, unsigned long ptlen, | |
315 | unsigned char *ct, | |
316 | unsigned char *tag, unsigned long *taglen, | |
317 | int direction, | |
318 | const unsigned char *B_0, | |
319 | const unsigned char *CTR, | |
320 | int ctrwidth); | |
321 | 328 | |
322 | 329 | int ccm_test(void); |
323 | 330 | |
489 | 496 | |
490 | 497 | #endif |
491 | 498 | |
499 | #ifdef LTC_CHACHA20POLY1305_MODE | |
500 | ||
501 | typedef struct { | |
502 | poly1305_state poly; | |
503 | chacha_state chacha; | |
504 | ulong64 aadlen; | |
505 | ulong64 ctlen; | |
506 | int aadflg; | |
507 | } chacha20poly1305_state; | |
508 | ||
509 | #define CHCHA20POLY1305_ENCRYPT 0 | |
510 | #define CHCHA20POLY1305_DECRYPT 1 | |
511 | ||
512 | int chacha20poly1305_init(chacha20poly1305_state *st, const unsigned char *key, unsigned long keylen); | |
513 | int chacha20poly1305_setiv(chacha20poly1305_state *st, const unsigned char *iv, unsigned long ivlen); | |
514 | int chacha20poly1305_setiv_rfc7905(chacha20poly1305_state *st, const unsigned char *iv, unsigned long ivlen, ulong64 sequence_number); | |
515 | int chacha20poly1305_add_aad(chacha20poly1305_state *st, const unsigned char *in, unsigned long inlen); | |
516 | int chacha20poly1305_encrypt(chacha20poly1305_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out); | |
517 | int chacha20poly1305_decrypt(chacha20poly1305_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out); | |
518 | int chacha20poly1305_done(chacha20poly1305_state *st, unsigned char *tag, unsigned long *taglen); | |
519 | int chacha20poly1305_memory(const unsigned char *key, unsigned long keylen, | |
520 | const unsigned char *iv, unsigned long ivlen, | |
521 | const unsigned char *aad, unsigned long aadlen, | |
522 | const unsigned char *in, unsigned long inlen, | |
523 | unsigned char *out, | |
524 | unsigned char *tag, unsigned long *taglen, | |
525 | int direction); | |
526 | int chacha20poly1305_test(void); | |
527 | ||
528 | #endif /* LTC_CHACHA20POLY1305_MODE */ | |
492 | 529 | |
493 | 530 | /* $Source$ */ |
494 | 531 | /* $Revision$ */ |
335 | 335 | #else |
336 | 336 | |
337 | 337 | /* rotates the hard way */ |
338 | #define ROL(x, y) ( (((ulong32)(x)<<(ulong32)((y)&31)) | (((ulong32)(x)&0xFFFFFFFFUL)>>(ulong32)(32-((y)&31)))) & 0xFFFFFFFFUL) | |
339 | #define ROR(x, y) ( ((((ulong32)(x)&0xFFFFFFFFUL)>>(ulong32)((y)&31)) | ((ulong32)(x)<<(ulong32)(32-((y)&31)))) & 0xFFFFFFFFUL) | |
340 | #define ROLc(x, y) ( (((ulong32)(x)<<(ulong32)((y)&31)) | (((ulong32)(x)&0xFFFFFFFFUL)>>(ulong32)(32-((y)&31)))) & 0xFFFFFFFFUL) | |
341 | #define RORc(x, y) ( ((((ulong32)(x)&0xFFFFFFFFUL)>>(ulong32)((y)&31)) | ((ulong32)(x)<<(ulong32)(32-((y)&31)))) & 0xFFFFFFFFUL) | |
338 | #define ROL(x, y) ( (((ulong32)(x)<<(ulong32)((y)&31)) | (((ulong32)(x)&0xFFFFFFFFUL)>>(ulong32)((32-((y)&31))&31))) & 0xFFFFFFFFUL) | |
339 | #define ROR(x, y) ( ((((ulong32)(x)&0xFFFFFFFFUL)>>(ulong32)((y)&31)) | ((ulong32)(x)<<(ulong32)((32-((y)&31))&31))) & 0xFFFFFFFFUL) | |
340 | #define ROLc(x, y) ( (((ulong32)(x)<<(ulong32)((y)&31)) | (((ulong32)(x)&0xFFFFFFFFUL)>>(ulong32)((32-((y)&31))&31))) & 0xFFFFFFFFUL) | |
341 | #define RORc(x, y) ( ((((ulong32)(x)&0xFFFFFFFFUL)>>(ulong32)((y)&31)) | ((ulong32)(x)<<(ulong32)((32-((y)&31))&31))) & 0xFFFFFFFFUL) | |
342 | 342 | |
343 | 343 | #endif |
344 | 344 | |
392 | 392 | |
393 | 393 | #define ROL64(x, y) \ |
394 | 394 | ( (((x)<<((ulong64)(y)&63)) | \ |
395 | (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)64-((y)&63)))) & CONST64(0xFFFFFFFFFFFFFFFF)) | |
395 | (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>(((ulong64)64-((y)&63))&63))) & CONST64(0xFFFFFFFFFFFFFFFF)) | |
396 | 396 | |
397 | 397 | #define ROR64(x, y) \ |
398 | 398 | ( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)(y)&CONST64(63))) | \ |
399 | ((x)<<((ulong64)(64-((y)&CONST64(63)))))) & CONST64(0xFFFFFFFFFFFFFFFF)) | |
399 | ((x)<<(((ulong64)64-((y)&63))&63))) & CONST64(0xFFFFFFFFFFFFFFFF)) | |
400 | 400 | |
401 | 401 | #define ROL64c(x, y) \ |
402 | 402 | ( (((x)<<((ulong64)(y)&63)) | \ |
403 | (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)64-((y)&63)))) & CONST64(0xFFFFFFFFFFFFFFFF)) | |
403 | (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>(((ulong64)64-((y)&63))&63))) & CONST64(0xFFFFFFFFFFFFFFFF)) | |
404 | 404 | |
405 | 405 | #define ROR64c(x, y) \ |
406 | 406 | ( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)(y)&CONST64(63))) | \ |
407 | ((x)<<((ulong64)(64-((y)&CONST64(63)))))) & CONST64(0xFFFFFFFFFFFFFFFF)) | |
407 | ((x)<<(((ulong64)64-((y)&63))&63))) & CONST64(0xFFFFFFFFFFFFFFFF)) | |
408 | 408 | |
409 | 409 | #endif |
410 | 410 |
104 | 104 | int compare_testvector(const void* is, const unsigned long is_len, const void* should, const unsigned long should_len, const char* what, int which); |
105 | 105 | #else |
106 | 106 | #define compare_testvector(is, is_len, should, should_len, what, which) \ |
107 | (((is_len) != (should_len)) || (XMEMCMP((is), (should), (is_len)) != 0)) | |
107 | ((((is_len) != (should_len)) || (XMEMCMP((is), (should), (is_len)) != 0)) ? 1 : 0) | |
108 | 108 | #endif |
109 | 109 | |
110 | 110 | /* $Source$ */ |
109 | 109 | /* PKCS #1 import/export */ |
110 | 110 | int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key); |
111 | 111 | int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key); |
112 | int rsa_import_pkcs8(const unsigned char *in, unsigned long inlen, rsa_key *key); | |
112 | ||
113 | int rsa_import_x509(const unsigned char *in, unsigned long inlen, rsa_key *key); | |
114 | int rsa_import_pkcs8(const unsigned char *in, unsigned long inlen, | |
115 | const void *passwd, unsigned long passwdlen, rsa_key *key); | |
113 | 116 | int rsa_import_radix(int radix, char *N, char *e, char *d, char *p, char *q, char *dP, char *dQ, char *qP, rsa_key *key); |
114 | 117 | #endif |
115 | 118 | |
310 | 313 | int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key); |
311 | 314 | int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key); |
312 | 315 | int ecc_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, const ltc_ecc_set_type *dp); |
313 | int ecc_import_pkcs8(unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp); | |
316 | 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); | |
314 | 317 | int ecc_export_full(unsigned char *out, unsigned long *outlen, int type, ecc_key *key); |
315 | 318 | int ecc_import_full(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp); |
316 | int ecc_export_point(unsigned char *out, unsigned long *outlen, void *x, void *y, unsigned long size, int compressed); | |
317 | int ecc_import_point(const unsigned char *in, unsigned long inlen, void *prime, void *a, void *b, void *x, void *y); | |
318 | 319 | int ecc_export_raw(unsigned char *out, unsigned long *outlen, int type, ecc_key *key); |
319 | 320 | int ecc_import_raw(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp); |
320 | 321 | |
357 | 358 | void ltc_ecc_del_point(ecc_point *p); |
358 | 359 | int ltc_ecc_is_valid_idx(int n); |
359 | 360 | int ltc_ecc_is_point(const ltc_ecc_set_type *dp, void *x, void *y); |
361 | int ltc_ecc_is_point_at_infinity(ecc_point *p, void *modulus); | |
362 | int ltc_ecc_import_point(const unsigned char *in, unsigned long inlen, void *prime, void *a, void *b, void *x, void *y); | |
363 | int ltc_ecc_export_point(unsigned char *out, unsigned long *outlen, void *x, void *y, unsigned long size, int compressed); | |
360 | 364 | |
361 | 365 | /* point ops (mp == montgomery digit) */ |
362 | 366 | #if !defined(LTC_MECC_ACCEL) || defined(LTM_DESC) || defined(GMP_DESC) |
512 | 516 | LTC_ASN1_TELETEX_STRING, |
513 | 517 | LTC_ASN1_CONSTRUCTED, |
514 | 518 | LTC_ASN1_CONTEXT_SPECIFIC, |
519 | /* 20 */ | |
520 | LTC_ASN1_GENERALIZEDTIME, | |
515 | 521 | } ltc_asn1_type; |
516 | 522 | |
517 | 523 | /** A LTC ASN.1 list type */ |
591 | 597 | int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out); |
592 | 598 | #define der_free_sequence_flexi der_sequence_free |
593 | 599 | void der_sequence_free(ltc_asn1_list *in); |
600 | void der_sequence_shrink(ltc_asn1_list *in); | |
594 | 601 | |
595 | 602 | /* BOOLEAN */ |
596 | 603 | int der_length_boolean(unsigned long *outlen); |
711 | 718 | |
712 | 719 | int der_length_utctime(ltc_utctime *utctime, unsigned long *outlen); |
713 | 720 | |
721 | /* GeneralizedTime */ | |
722 | typedef struct { | |
723 | unsigned YYYY, /* year */ | |
724 | MM, /* month */ | |
725 | DD, /* day */ | |
726 | hh, /* hour */ | |
727 | mm, /* minute */ | |
728 | ss, /* second */ | |
729 | fs, /* fractional seconds */ | |
730 | off_dir, /* timezone offset direction 0 == +, 1 == - */ | |
731 | off_hh, /* timezone offset hours */ | |
732 | off_mm; /* timezone offset minutes */ | |
733 | } ltc_generalizedtime; | |
734 | ||
735 | int der_encode_generalizedtime(ltc_generalizedtime *gtime, | |
736 | unsigned char *out, unsigned long *outlen); | |
737 | ||
738 | int der_decode_generalizedtime(const unsigned char *in, unsigned long *inlen, | |
739 | ltc_generalizedtime *out); | |
740 | ||
741 | int der_length_generalizedtime(ltc_generalizedtime *gtime, unsigned long *outlen); | |
742 | ||
714 | 743 | |
715 | 744 | #endif |
716 | 745 |
14 | 14 | }; |
15 | 15 | #endif |
16 | 16 | |
17 | #ifdef LTC_CHACHA20_PRNG | |
18 | struct chacha20_prng { | |
19 | chacha_state s; /* chacha state */ | |
20 | unsigned char ent[40]; /* entropy buffer */ | |
21 | unsigned long idx; /* entropy counter */ | |
22 | short ready; /* ready flag 0-1 */ | |
23 | }; | |
24 | #endif | |
25 | ||
17 | 26 | #ifdef LTC_FORTUNA |
18 | 27 | struct fortuna_prng { |
19 | 28 | hash_state pool[LTC_FORTUNA_POOLS]; /* the pools */ |
53 | 62 | #endif |
54 | 63 | #ifdef LTC_RC4 |
55 | 64 | struct rc4_prng rc4; |
65 | #endif | |
66 | #ifdef LTC_CHACHA20_PRNG | |
67 | struct chacha20_prng chacha; | |
56 | 68 | #endif |
57 | 69 | #ifdef LTC_FORTUNA |
58 | 70 | struct fortuna_prng fortuna; |
146 | 158 | int rc4_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng); |
147 | 159 | int rc4_ready(prng_state *prng); |
148 | 160 | unsigned long rc4_read(unsigned char *out, unsigned long outlen, prng_state *prng); |
149 | int rc4_done(prng_state *prng); | |
161 | int rc4_prng_done(prng_state *prng); | |
150 | 162 | int rc4_export(unsigned char *out, unsigned long *outlen, prng_state *prng); |
151 | 163 | int rc4_import(const unsigned char *in, unsigned long inlen, prng_state *prng); |
152 | int rc4_test(void); | |
164 | int rc4_prng_test(void); | |
153 | 165 | extern const struct ltc_prng_descriptor rc4_desc; |
166 | #endif | |
167 | ||
168 | #ifdef LTC_CHACHA20_PRNG | |
169 | int chacha20_prng_start(prng_state *prng); | |
170 | int chacha20_prng_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng); | |
171 | int chacha20_prng_ready(prng_state *prng); | |
172 | unsigned long chacha20_prng_read(unsigned char *out, unsigned long outlen, prng_state *prng); | |
173 | int chacha20_prng_done(prng_state *prng); | |
174 | int chacha20_prng_export(unsigned char *out, unsigned long *outlen, prng_state *prng); | |
175 | int chacha20_prng_import(const unsigned char *in, unsigned long inlen, prng_state *prng); | |
176 | int chacha20_prng_test(void); | |
177 | extern const struct ltc_prng_descriptor chacha20_prng_desc; | |
154 | 178 | #endif |
155 | 179 | |
156 | 180 | #ifdef LTC_SPRNG |
170 | 194 | int sober128_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng); |
171 | 195 | int sober128_ready(prng_state *prng); |
172 | 196 | unsigned long sober128_read(unsigned char *out, unsigned long outlen, prng_state *prng); |
173 | int sober128_done(prng_state *prng); | |
197 | int sober128_prng_done(prng_state *prng); | |
174 | 198 | int sober128_export(unsigned char *out, unsigned long *outlen, prng_state *prng); |
175 | 199 | int sober128_import(const unsigned char *in, unsigned long inlen, prng_state *prng); |
176 | int sober128_test(void); | |
200 | int sober128_prng_test(void); | |
177 | 201 | extern const struct ltc_prng_descriptor sober128_desc; |
178 | 202 | #endif |
179 | 203 | |
192 | 216 | |
193 | 217 | int rng_make_prng(int bits, int wprng, prng_state *prng, void (*callback)(void)); |
194 | 218 | |
219 | #ifdef LTC_PRNG_ENABLE_LTC_RNG | |
220 | extern unsigned long (*ltc_rng)(unsigned char *out, unsigned long outlen, | |
221 | void (*callback)(void)); | |
222 | #endif | |
223 | ||
195 | 224 | |
196 | 225 | /* $Source$ */ |
197 | 226 | /* $Revision$ */ |
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 | ||
9 | /* The implementation is based on: | |
10 | * Public Domain poly1305 from Andrew Moon | |
11 | * https://github.com/floodyberry/poly1305-donna | |
12 | */ | |
13 | ||
14 | #include "tomcrypt.h" | |
15 | ||
16 | #ifdef LTC_POLY1305 | |
17 | ||
18 | /* internal only */ | |
19 | static void _poly1305_block(poly1305_state *st, const unsigned char *in, unsigned long inlen) | |
20 | { | |
21 | const unsigned long hibit = (st->final) ? 0 : (1UL << 24); /* 1 << 128 */ | |
22 | ulong32 r0,r1,r2,r3,r4; | |
23 | ulong32 s1,s2,s3,s4; | |
24 | ulong32 h0,h1,h2,h3,h4; | |
25 | ulong32 tmp; | |
26 | ulong64 d0,d1,d2,d3,d4; | |
27 | ulong32 c; | |
28 | ||
29 | r0 = st->r[0]; | |
30 | r1 = st->r[1]; | |
31 | r2 = st->r[2]; | |
32 | r3 = st->r[3]; | |
33 | r4 = st->r[4]; | |
34 | ||
35 | s1 = r1 * 5; | |
36 | s2 = r2 * 5; | |
37 | s3 = r3 * 5; | |
38 | s4 = r4 * 5; | |
39 | ||
40 | h0 = st->h[0]; | |
41 | h1 = st->h[1]; | |
42 | h2 = st->h[2]; | |
43 | h3 = st->h[3]; | |
44 | h4 = st->h[4]; | |
45 | ||
46 | while (inlen >= 16) { | |
47 | /* h += in[i] */ | |
48 | LOAD32L(tmp, in+ 0); h0 += (tmp ) & 0x3ffffff; | |
49 | LOAD32L(tmp, in+ 3); h1 += (tmp >> 2) & 0x3ffffff; | |
50 | LOAD32L(tmp, in+ 6); h2 += (tmp >> 4) & 0x3ffffff; | |
51 | LOAD32L(tmp, in+ 9); h3 += (tmp >> 6) & 0x3ffffff; | |
52 | LOAD32L(tmp, in+12); h4 += (tmp >> 8) | hibit; | |
53 | ||
54 | /* h *= r */ | |
55 | d0 = ((ulong64)h0 * r0) + ((ulong64)h1 * s4) + ((ulong64)h2 * s3) + ((ulong64)h3 * s2) + ((ulong64)h4 * s1); | |
56 | d1 = ((ulong64)h0 * r1) + ((ulong64)h1 * r0) + ((ulong64)h2 * s4) + ((ulong64)h3 * s3) + ((ulong64)h4 * s2); | |
57 | d2 = ((ulong64)h0 * r2) + ((ulong64)h1 * r1) + ((ulong64)h2 * r0) + ((ulong64)h3 * s4) + ((ulong64)h4 * s3); | |
58 | d3 = ((ulong64)h0 * r3) + ((ulong64)h1 * r2) + ((ulong64)h2 * r1) + ((ulong64)h3 * r0) + ((ulong64)h4 * s4); | |
59 | d4 = ((ulong64)h0 * r4) + ((ulong64)h1 * r3) + ((ulong64)h2 * r2) + ((ulong64)h3 * r1) + ((ulong64)h4 * r0); | |
60 | ||
61 | /* (partial) h %= p */ | |
62 | c = (ulong32)(d0 >> 26); h0 = (ulong32)d0 & 0x3ffffff; | |
63 | d1 += c; c = (ulong32)(d1 >> 26); h1 = (ulong32)d1 & 0x3ffffff; | |
64 | d2 += c; c = (ulong32)(d2 >> 26); h2 = (ulong32)d2 & 0x3ffffff; | |
65 | d3 += c; c = (ulong32)(d3 >> 26); h3 = (ulong32)d3 & 0x3ffffff; | |
66 | d4 += c; c = (ulong32)(d4 >> 26); h4 = (ulong32)d4 & 0x3ffffff; | |
67 | h0 += c * 5; c = (h0 >> 26); h0 = h0 & 0x3ffffff; | |
68 | h1 += c; | |
69 | ||
70 | in += 16; | |
71 | inlen -= 16; | |
72 | } | |
73 | ||
74 | st->h[0] = h0; | |
75 | st->h[1] = h1; | |
76 | st->h[2] = h2; | |
77 | st->h[3] = h3; | |
78 | st->h[4] = h4; | |
79 | } | |
80 | ||
81 | /** | |
82 | Initialize an POLY1305 context. | |
83 | @param st The POLY1305 state | |
84 | @param key The secret key | |
85 | @param keylen The length of the secret key (octets) | |
86 | @return CRYPT_OK if successful | |
87 | */ | |
88 | int poly1305_init(poly1305_state *st, const unsigned char *key, unsigned long keylen) | |
89 | { | |
90 | LTC_ARGCHK(st != NULL); | |
91 | LTC_ARGCHK(key != NULL); | |
92 | LTC_ARGCHK(keylen == 32); | |
93 | ||
94 | /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */ | |
95 | LOAD32L(st->r[0], key + 0); st->r[0] = (st->r[0] ) & 0x3ffffff; | |
96 | LOAD32L(st->r[1], key + 3); st->r[1] = (st->r[1] >> 2) & 0x3ffff03; | |
97 | LOAD32L(st->r[2], key + 6); st->r[2] = (st->r[2] >> 4) & 0x3ffc0ff; | |
98 | LOAD32L(st->r[3], key + 9); st->r[3] = (st->r[3] >> 6) & 0x3f03fff; | |
99 | LOAD32L(st->r[4], key + 12); st->r[4] = (st->r[4] >> 8) & 0x00fffff; | |
100 | ||
101 | /* h = 0 */ | |
102 | st->h[0] = 0; | |
103 | st->h[1] = 0; | |
104 | st->h[2] = 0; | |
105 | st->h[3] = 0; | |
106 | st->h[4] = 0; | |
107 | ||
108 | /* save pad for later */ | |
109 | LOAD32L(st->pad[0], key + 16); | |
110 | LOAD32L(st->pad[1], key + 20); | |
111 | LOAD32L(st->pad[2], key + 24); | |
112 | LOAD32L(st->pad[3], key + 28); | |
113 | ||
114 | st->leftover = 0; | |
115 | st->final = 0; | |
116 | return CRYPT_OK; | |
117 | } | |
118 | ||
119 | /** | |
120 | Process data through POLY1305 | |
121 | @param st The POLY1305 state | |
122 | @param in The data to send through HMAC | |
123 | @param inlen The length of the data to HMAC (octets) | |
124 | @return CRYPT_OK if successful | |
125 | */ | |
126 | int poly1305_process(poly1305_state *st, const unsigned char *in, unsigned long inlen) | |
127 | { | |
128 | unsigned long i; | |
129 | ||
130 | if (inlen == 0) return CRYPT_OK; /* nothing to do */ | |
131 | LTC_ARGCHK(st != NULL); | |
132 | LTC_ARGCHK(in != NULL); | |
133 | ||
134 | /* handle leftover */ | |
135 | if (st->leftover) { | |
136 | unsigned long want = (16 - st->leftover); | |
137 | if (want > inlen) want = inlen; | |
138 | for (i = 0; i < want; i++) st->buffer[st->leftover + i] = in[i]; | |
139 | inlen -= want; | |
140 | in += want; | |
141 | st->leftover += want; | |
142 | if (st->leftover < 16) return CRYPT_OK; | |
143 | _poly1305_block(st, st->buffer, 16); | |
144 | st->leftover = 0; | |
145 | } | |
146 | ||
147 | /* process full blocks */ | |
148 | if (inlen >= 16) { | |
149 | unsigned long want = (inlen & ~(16 - 1)); | |
150 | _poly1305_block(st, in, want); | |
151 | in += want; | |
152 | inlen -= want; | |
153 | } | |
154 | ||
155 | /* store leftover */ | |
156 | if (inlen) { | |
157 | for (i = 0; i < inlen; i++) st->buffer[st->leftover + i] = in[i]; | |
158 | st->leftover += inlen; | |
159 | } | |
160 | return CRYPT_OK; | |
161 | } | |
162 | ||
163 | /** | |
164 | Terminate a POLY1305 session | |
165 | @param st The POLY1305 state | |
166 | @param out [out] The destination of the POLY1305 authentication tag | |
167 | @param outlen [in/out] The max size and resulting size of the POLY1305 authentication tag | |
168 | @return CRYPT_OK if successful | |
169 | */ | |
170 | int poly1305_done(poly1305_state *st, unsigned char *mac, unsigned long *maclen) | |
171 | { | |
172 | ulong32 h0,h1,h2,h3,h4,c; | |
173 | ulong32 g0,g1,g2,g3,g4; | |
174 | ulong64 f; | |
175 | ulong32 mask; | |
176 | ||
177 | LTC_ARGCHK(st != NULL); | |
178 | LTC_ARGCHK(mac != NULL); | |
179 | LTC_ARGCHK(maclen != NULL); | |
180 | LTC_ARGCHK(*maclen >= 16); | |
181 | ||
182 | /* process the remaining block */ | |
183 | if (st->leftover) { | |
184 | unsigned long i = st->leftover; | |
185 | st->buffer[i++] = 1; | |
186 | for (; i < 16; i++) st->buffer[i] = 0; | |
187 | st->final = 1; | |
188 | _poly1305_block(st, st->buffer, 16); | |
189 | } | |
190 | ||
191 | /* fully carry h */ | |
192 | h0 = st->h[0]; | |
193 | h1 = st->h[1]; | |
194 | h2 = st->h[2]; | |
195 | h3 = st->h[3]; | |
196 | h4 = st->h[4]; | |
197 | ||
198 | c = h1 >> 26; h1 = h1 & 0x3ffffff; | |
199 | h2 += c; c = h2 >> 26; h2 = h2 & 0x3ffffff; | |
200 | h3 += c; c = h3 >> 26; h3 = h3 & 0x3ffffff; | |
201 | h4 += c; c = h4 >> 26; h4 = h4 & 0x3ffffff; | |
202 | h0 += c * 5; c = h0 >> 26; h0 = h0 & 0x3ffffff; | |
203 | h1 += c; | |
204 | ||
205 | /* compute h + -p */ | |
206 | g0 = h0 + 5; c = g0 >> 26; g0 &= 0x3ffffff; | |
207 | g1 = h1 + c; c = g1 >> 26; g1 &= 0x3ffffff; | |
208 | g2 = h2 + c; c = g2 >> 26; g2 &= 0x3ffffff; | |
209 | g3 = h3 + c; c = g3 >> 26; g3 &= 0x3ffffff; | |
210 | g4 = h4 + c - (1UL << 26); | |
211 | ||
212 | /* select h if h < p, or h + -p if h >= p */ | |
213 | mask = (g4 >> 31) - 1; | |
214 | g0 &= mask; | |
215 | g1 &= mask; | |
216 | g2 &= mask; | |
217 | g3 &= mask; | |
218 | g4 &= mask; | |
219 | mask = ~mask; | |
220 | h0 = (h0 & mask) | g0; | |
221 | h1 = (h1 & mask) | g1; | |
222 | h2 = (h2 & mask) | g2; | |
223 | h3 = (h3 & mask) | g3; | |
224 | h4 = (h4 & mask) | g4; | |
225 | ||
226 | /* h = h % (2^128) */ | |
227 | h0 = ((h0 ) | (h1 << 26)) & 0xffffffff; | |
228 | h1 = ((h1 >> 6) | (h2 << 20)) & 0xffffffff; | |
229 | h2 = ((h2 >> 12) | (h3 << 14)) & 0xffffffff; | |
230 | h3 = ((h3 >> 18) | (h4 << 8)) & 0xffffffff; | |
231 | ||
232 | /* mac = (h + pad) % (2^128) */ | |
233 | f = (ulong64)h0 + st->pad[0] ; h0 = (ulong32)f; | |
234 | f = (ulong64)h1 + st->pad[1] + (f >> 32); h1 = (ulong32)f; | |
235 | f = (ulong64)h2 + st->pad[2] + (f >> 32); h2 = (ulong32)f; | |
236 | f = (ulong64)h3 + st->pad[3] + (f >> 32); h3 = (ulong32)f; | |
237 | ||
238 | STORE32L(h0, mac + 0); | |
239 | STORE32L(h1, mac + 4); | |
240 | STORE32L(h2, mac + 8); | |
241 | STORE32L(h3, mac + 12); | |
242 | ||
243 | /* zero out the state */ | |
244 | st->h[0] = 0; | |
245 | st->h[1] = 0; | |
246 | st->h[2] = 0; | |
247 | st->h[3] = 0; | |
248 | st->h[4] = 0; | |
249 | st->r[0] = 0; | |
250 | st->r[1] = 0; | |
251 | st->r[2] = 0; | |
252 | st->r[3] = 0; | |
253 | st->r[4] = 0; | |
254 | st->pad[0] = 0; | |
255 | st->pad[1] = 0; | |
256 | st->pad[2] = 0; | |
257 | st->pad[3] = 0; | |
258 | ||
259 | *maclen = 16; | |
260 | return CRYPT_OK; | |
261 | } | |
262 | ||
263 | #endif |
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 | ||
9 | /* The implementation is based on: | |
10 | * Public Domain poly1305 from Andrew Moon | |
11 | * https://github.com/floodyberry/poly1305-donna | |
12 | */ | |
13 | ||
14 | #include "tomcrypt.h" | |
15 | ||
16 | #ifdef LTC_POLY1305 | |
17 | ||
18 | /** | |
19 | POLY1305 a file | |
20 | @param fname The name of the file you wish to POLY1305 | |
21 | @param key The secret key | |
22 | @param keylen The length of the secret key | |
23 | @param out [out] The POLY1305 authentication tag | |
24 | @param outlen [in/out] The max size and resulting size of the authentication tag | |
25 | @return CRYPT_OK if successful, CRYPT_NOP if file support has been disabled | |
26 | */ | |
27 | int poly1305_file(const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen) | |
28 | { | |
29 | #ifdef LTC_NO_FILE | |
30 | return CRYPT_NOP; | |
31 | #else | |
32 | poly1305_state st; | |
33 | FILE *in; | |
34 | unsigned char *buf; | |
35 | size_t x; | |
36 | int err; | |
37 | ||
38 | LTC_ARGCHK(fname != NULL); | |
39 | LTC_ARGCHK(key != NULL); | |
40 | LTC_ARGCHK(mac != NULL); | |
41 | LTC_ARGCHK(maclen != NULL); | |
42 | ||
43 | if ((in = fopen(fname, "rb")) == NULL) { return CRYPT_FILE_NOTFOUND; } | |
44 | if ((buf = XMALLOC(LTC_FILE_READ_BUFSIZE)) == NULL) { return CRYPT_MEM; } | |
45 | if ((err = poly1305_init(&st, key, keylen)) != CRYPT_OK) { goto LBL_ERR; } | |
46 | ||
47 | do { | |
48 | x = fread(buf, 1, LTC_FILE_READ_BUFSIZE, in); | |
49 | if ((err = poly1305_process(&st, buf, (unsigned long)x)) != CRYPT_OK) { | |
50 | fclose(in); | |
51 | goto LBL_ERR; | |
52 | } | |
53 | } while (x == LTC_FILE_READ_BUFSIZE); | |
54 | if (fclose(in) != 0) { | |
55 | err = CRYPT_ERROR; | |
56 | goto LBL_ERR; | |
57 | } | |
58 | err = poly1305_done(&st, mac, maclen); | |
59 | ||
60 | LBL_ERR: | |
61 | #ifdef LTC_CLEAN_STACK | |
62 | zeromem(&st, sizeof(poly1305_state)); | |
63 | #endif | |
64 | XFREE(buf); | |
65 | return err; | |
66 | #endif | |
67 | }; | |
68 | ||
69 | #endif |
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 | ||
9 | /* The implementation is based on: | |
10 | * Public Domain poly1305 from Andrew Moon | |
11 | * https://github.com/floodyberry/poly1305-donna | |
12 | */ | |
13 | ||
14 | #include "tomcrypt.h" | |
15 | ||
16 | #ifdef LTC_POLY1305 | |
17 | ||
18 | /** | |
19 | POLY1305 a block of memory to produce the authentication tag | |
20 | @param key The secret key | |
21 | @param keylen The length of the secret key (octets) | |
22 | @param in The data to POLY1305 | |
23 | @param inlen The length of the data to POLY1305 (octets) | |
24 | @param mac [out] Destination of the authentication tag | |
25 | @param maclen [in/out] Max size and resulting size of authentication tag | |
26 | @return CRYPT_OK if successful | |
27 | */ | |
28 | int poly1305_memory(const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *mac, unsigned long *maclen) | |
29 | { | |
30 | poly1305_state st; | |
31 | int err; | |
32 | ||
33 | LTC_ARGCHK(key != NULL); | |
34 | LTC_ARGCHK(in != NULL); | |
35 | LTC_ARGCHK(mac != NULL); | |
36 | LTC_ARGCHK(maclen != NULL); | |
37 | ||
38 | if ((err = poly1305_init(&st, key, keylen)) != CRYPT_OK) { goto LBL_ERR; } | |
39 | if ((err = poly1305_process(&st, in, inlen)) != CRYPT_OK) { goto LBL_ERR; } | |
40 | err = poly1305_done(&st, mac, maclen); | |
41 | LBL_ERR: | |
42 | #ifdef LTC_CLEAN_STACK | |
43 | zeromem(&st, sizeof(poly1305_state)); | |
44 | #endif | |
45 | return err; | |
46 | }; | |
47 | ||
48 | #endif |
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 | ||
9 | /* The implementation is based on: | |
10 | * Public Domain poly1305 from Andrew Moon | |
11 | * https://github.com/floodyberry/poly1305-donna | |
12 | */ | |
13 | ||
14 | #include "tomcrypt.h" | |
15 | #include <stdarg.h> | |
16 | ||
17 | #ifdef LTC_POLY1305 | |
18 | ||
19 | /** | |
20 | POLY1305 multiple blocks of memory to produce the authentication tag | |
21 | @param key The secret key | |
22 | @param keylen The length of the secret key (octets) | |
23 | @param out [out] Destination of the authentication tag | |
24 | @param outlen [in/out] Max size and resulting size of authentication tag | |
25 | @param in The data to POLY1305 | |
26 | @param inlen The length of the data to POLY1305 (octets) | |
27 | @param ... tuples of (data,len) pairs to POLY1305, terminated with a (NULL,x) (x=don't care) | |
28 | @return CRYPT_OK if successful | |
29 | */ | |
30 | int poly1305_memory_multi(const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen, const unsigned char *in, unsigned long inlen, ...) | |
31 | { | |
32 | poly1305_state st; | |
33 | int err; | |
34 | va_list args; | |
35 | const unsigned char *curptr; | |
36 | unsigned long curlen; | |
37 | ||
38 | LTC_ARGCHK(key != NULL); | |
39 | LTC_ARGCHK(in != NULL); | |
40 | LTC_ARGCHK(mac != NULL); | |
41 | LTC_ARGCHK(maclen != NULL); | |
42 | ||
43 | va_start(args, inlen); | |
44 | curptr = in; | |
45 | curlen = inlen; | |
46 | if ((err = poly1305_init(&st, key, keylen)) != CRYPT_OK) { goto LBL_ERR; } | |
47 | for (;;) { | |
48 | if ((err = poly1305_process(&st, curptr, curlen)) != CRYPT_OK) { goto LBL_ERR; } | |
49 | curptr = va_arg(args, const unsigned char*); | |
50 | if (curptr == NULL) break; | |
51 | curlen = va_arg(args, unsigned long); | |
52 | } | |
53 | err = poly1305_done(&st, mac, maclen); | |
54 | LBL_ERR: | |
55 | #ifdef LTC_CLEAN_STACK | |
56 | zeromem(&st, sizeof(poly1305_state)); | |
57 | #endif | |
58 | va_end(args); | |
59 | return err; | |
60 | }; | |
61 | ||
62 | #endif |
123 | 123 | #if defined(LTC_CAMELLIA) |
124 | 124 | " Camellia\n" |
125 | 125 | #endif |
126 | #if defined(LTC_CHACHA) | |
127 | " ChaCha\n" | |
128 | #endif | |
126 | 129 | |
127 | 130 | "\nHashes built-in:\n" |
131 | #if defined(LTC_SHA3) | |
132 | " SHA3\n" | |
133 | #endif | |
128 | 134 | #if defined(LTC_SHA512) |
129 | 135 | " SHA-512\n" |
130 | 136 | #endif |
226 | 232 | #if defined(LTC_F9_MODE) |
227 | 233 | " F9\n" |
228 | 234 | #endif |
235 | #if defined(LTC_POLY1305) | |
236 | " POLY1305\n" | |
237 | #endif | |
229 | 238 | |
230 | 239 | "\nENC + AUTH modes:\n" |
231 | 240 | #if defined(LTC_EAX_MODE) |
250 | 259 | #endif |
251 | 260 | "\n" |
252 | 261 | #endif |
262 | #if defined(LTC_CHACHA20POLY1305_MODE) | |
263 | " CHACHA20POLY1305\n" | |
264 | #endif | |
253 | 265 | |
254 | 266 | "\nPRNG:\n" |
255 | 267 | #if defined(LTC_YARROW) |
260 | 272 | #endif |
261 | 273 | #if defined(LTC_RC4) |
262 | 274 | " RC4\n" |
275 | #endif | |
276 | #if defined(LTC_CHACHA20_PRNG) | |
277 | " ChaCha20\n" | |
263 | 278 | #endif |
264 | 279 | #if defined(LTC_FORTUNA) |
265 | 280 | " Fortuna (" NAME_VALUE(LTC_FORTUNA_POOLS) ", " NAME_VALUE(LTC_FORTUNA_WD) ")\n" |
370 | 385 | #if defined(LTC_RNG_MAKE_PRNG) |
371 | 386 | " LTC_RNG_MAKE_PRNG " |
372 | 387 | #endif |
388 | #if defined(LTC_PRNG_ENABLE_LTC_RNG) | |
389 | " LTC_PRNG_ENABLE_LTC_RNG " | |
390 | #endif | |
373 | 391 | #if defined(LTC_HASH_HELPERS) |
374 | 392 | " LTC_HASH_HELPERS " |
375 | 393 | #endif |
387 | 405 | #endif |
388 | 406 | #if defined(LTC_NO_FILE) |
389 | 407 | " LTC_NO_FILE " |
408 | #endif | |
409 | #if defined(LTC_FILE_READ_BUFSIZE) | |
410 | " " NAME_VALUE(LTC_FILE_READ_BUFSIZE) " " | |
390 | 411 | #endif |
391 | 412 | #if defined(LTC_FAST) |
392 | 413 | " LTC_FAST " |
44 | 44 | "File Not Found", |
45 | 45 | |
46 | 46 | "Invalid PK type.", |
47 | "Invalid PK system.", | |
48 | "Duplicate PK key found on keyring.", | |
49 | "Key not found in keyring.", | |
47 | ||
48 | "An overflow of a value was detected/prevented.", | |
49 | ||
50 | "UNUSED1.", | |
51 | "UNUSED2.", | |
52 | ||
50 | 53 | "Invalid sized parameter.", |
51 | 54 | |
52 | 55 | "Invalid size for prime.", |
18 | 18 | /** |
19 | 19 | Compare two blocks of memory for inequality. |
20 | 20 | |
21 | The usage is similar to that of standard memcmp(), but you can only test | |
21 | The usage is similar to that of standard memcmp, but you can only test | |
22 | 22 | if the memory is equal or not - you can not determine by how much the |
23 | 23 | first different byte differs. |
24 | 24 |
185 | 185 | } |
186 | 186 | break; |
187 | 187 | |
188 | case LTC_ASN1_GENERALIZEDTIME: | |
189 | z = *inlen; | |
190 | if (der_decode_generalizedtime(in, &z, data) == CRYPT_OK) { | |
191 | list[x].used = 1; | |
192 | *inlen = z; | |
193 | return CRYPT_OK; | |
194 | } | |
195 | break; | |
196 | ||
188 | 197 | case LTC_ASN1_SET: |
189 | 198 | case LTC_ASN1_SETOF: |
190 | 199 | case LTC_ASN1_SEQUENCE: |
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 | * Tom St Denis, tomstdenis@gmail.com, http://libtom.org | |
9 | */ | |
10 | #include "tomcrypt.h" | |
11 | ||
12 | /** | |
13 | @file der_decode_generalizedtime.c | |
14 | ASN.1 DER, decode a GeneralizedTime, Steffen Jaeckel | |
15 | Based on der_decode_utctime.c | |
16 | */ | |
17 | ||
18 | #ifdef LTC_DER | |
19 | ||
20 | static int char_to_int(unsigned char x) | |
21 | { | |
22 | switch (x) { | |
23 | case '0': return 0; | |
24 | case '1': return 1; | |
25 | case '2': return 2; | |
26 | case '3': return 3; | |
27 | case '4': return 4; | |
28 | case '5': return 5; | |
29 | case '6': return 6; | |
30 | case '7': return 7; | |
31 | case '8': return 8; | |
32 | case '9': return 9; | |
33 | } | |
34 | return 100; | |
35 | } | |
36 | ||
37 | #define DECODE_V(y, max) do {\ | |
38 | y = char_to_int(buf[x])*10 + char_to_int(buf[x+1]); \ | |
39 | if (y >= max) return CRYPT_INVALID_PACKET; \ | |
40 | x += 2; \ | |
41 | } while(0) | |
42 | ||
43 | #define DECODE_V4(y, max) do {\ | |
44 | y = char_to_int(buf[x])*1000 + char_to_int(buf[x+1])*100 + char_to_int(buf[x+2])*10 + char_to_int(buf[x+3]); \ | |
45 | if (y >= max) return CRYPT_INVALID_PACKET; \ | |
46 | x += 4; \ | |
47 | } while(0) | |
48 | ||
49 | /** | |
50 | Decodes a Generalized time structure in DER format (reads all 6 valid encoding formats) | |
51 | @param in Input buffer | |
52 | @param inlen Length of input buffer in octets | |
53 | @param out [out] Destination of Generalized time structure | |
54 | @return CRYPT_OK if successful | |
55 | */ | |
56 | int der_decode_generalizedtime(const unsigned char *in, unsigned long *inlen, | |
57 | ltc_generalizedtime *out) | |
58 | { | |
59 | unsigned char buf[32]; | |
60 | unsigned long x; | |
61 | int y; | |
62 | ||
63 | LTC_ARGCHK(in != NULL); | |
64 | LTC_ARGCHK(inlen != NULL); | |
65 | LTC_ARGCHK(out != NULL); | |
66 | ||
67 | /* check header */ | |
68 | if (*inlen < 2UL || (in[1] >= sizeof(buf)) || ((in[1] + 2UL) > *inlen)) { | |
69 | return CRYPT_INVALID_PACKET; | |
70 | } | |
71 | ||
72 | /* decode the string */ | |
73 | for (x = 0; x < in[1]; x++) { | |
74 | y = der_ia5_value_decode(in[x+2]); | |
75 | if (y == -1) { | |
76 | return CRYPT_INVALID_PACKET; | |
77 | } | |
78 | if (!((y >= '0' && y <= '9') | |
79 | || y == 'Z' || y == '.' | |
80 | || y == '+' || y == '-')) { | |
81 | return CRYPT_INVALID_PACKET; | |
82 | } | |
83 | buf[x] = y; | |
84 | } | |
85 | *inlen = 2 + x; | |
86 | ||
87 | if (x < 15) { | |
88 | return CRYPT_INVALID_PACKET; | |
89 | } | |
90 | ||
91 | /* possible encodings are | |
92 | YYYYMMDDhhmmssZ | |
93 | YYYYMMDDhhmmss+hh'mm' | |
94 | YYYYMMDDhhmmss-hh'mm' | |
95 | YYYYMMDDhhmmss.fsZ | |
96 | YYYYMMDDhhmmss.fs+hh'mm' | |
97 | YYYYMMDDhhmmss.fs-hh'mm' | |
98 | ||
99 | So let's do a trivial decode upto [including] ss | |
100 | */ | |
101 | ||
102 | x = 0; | |
103 | DECODE_V4(out->YYYY, 10000); | |
104 | DECODE_V(out->MM, 13); | |
105 | DECODE_V(out->DD, 32); | |
106 | DECODE_V(out->hh, 24); | |
107 | DECODE_V(out->mm, 60); | |
108 | DECODE_V(out->ss, 60); | |
109 | ||
110 | /* clear fractional seconds info */ | |
111 | out->fs = 0; | |
112 | ||
113 | /* now is it Z or . */ | |
114 | if (buf[x] == 'Z') { | |
115 | return CRYPT_OK; | |
116 | } else if (buf[x] == '.') { | |
117 | x++; | |
118 | while (buf[x] >= '0' && buf[x] <= '9') { | |
119 | unsigned fs = out->fs; | |
120 | if (x >= sizeof(buf)) return CRYPT_INVALID_PACKET; | |
121 | out->fs *= 10; | |
122 | out->fs += char_to_int(buf[x]); | |
123 | if (fs > out->fs) return CRYPT_OVERFLOW; | |
124 | x++; | |
125 | } | |
126 | } | |
127 | ||
128 | /* now is it Z, +, - */ | |
129 | if (buf[x] == 'Z') { | |
130 | return CRYPT_OK; | |
131 | } else if (buf[x] == '+' || buf[x] == '-') { | |
132 | out->off_dir = (buf[x++] == '+') ? 0 : 1; | |
133 | DECODE_V(out->off_hh, 24); | |
134 | DECODE_V(out->off_mm, 60); | |
135 | return CRYPT_OK; | |
136 | } else { | |
137 | return CRYPT_INVALID_PACKET; | |
138 | } | |
139 | } | |
140 | ||
141 | #endif | |
142 | ||
143 | /* $Source$ */ | |
144 | /* $Revision$ */ | |
145 | /* $Date$ */ |
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 | * Tom St Denis, tomstdenis@gmail.com, http://libtom.org | |
9 | */ | |
10 | #include "tomcrypt.h" | |
11 | ||
12 | /** | |
13 | @file der_encode_utctime.c | |
14 | ASN.1 DER, encode a GeneralizedTime, Steffen Jaeckel | |
15 | Based on der_encode_utctime.c | |
16 | */ | |
17 | ||
18 | #ifdef LTC_DER | |
19 | ||
20 | static const char * const baseten = "0123456789"; | |
21 | ||
22 | #define STORE_V(y) do {\ | |
23 | out[x++] = der_ia5_char_encode(baseten[(y/10) % 10]); \ | |
24 | out[x++] = der_ia5_char_encode(baseten[y % 10]); \ | |
25 | } while(0) | |
26 | ||
27 | #define STORE_V4(y) do {\ | |
28 | out[x++] = der_ia5_char_encode(baseten[(y/1000) % 10]); \ | |
29 | out[x++] = der_ia5_char_encode(baseten[(y/100) % 10]); \ | |
30 | out[x++] = der_ia5_char_encode(baseten[(y/10) % 10]); \ | |
31 | out[x++] = der_ia5_char_encode(baseten[y % 10]); \ | |
32 | } while(0) | |
33 | ||
34 | /** | |
35 | Encodes a Generalized time structure in DER format | |
36 | @param utctime The UTC time structure to encode | |
37 | @param out The destination of the DER encoding of the UTC time structure | |
38 | @param outlen [in/out] The length of the DER encoding | |
39 | @return CRYPT_OK if successful | |
40 | */ | |
41 | int der_encode_generalizedtime(ltc_generalizedtime *gtime, | |
42 | unsigned char *out, unsigned long *outlen) | |
43 | { | |
44 | unsigned long x, tmplen; | |
45 | int err; | |
46 | ||
47 | LTC_ARGCHK(gtime != NULL); | |
48 | LTC_ARGCHK(out != NULL); | |
49 | LTC_ARGCHK(outlen != NULL); | |
50 | ||
51 | if ((err = der_length_generalizedtime(gtime, &tmplen)) != CRYPT_OK) { | |
52 | return err; | |
53 | } | |
54 | if (tmplen > *outlen) { | |
55 | *outlen = tmplen; | |
56 | return CRYPT_BUFFER_OVERFLOW; | |
57 | } | |
58 | ||
59 | /* store header */ | |
60 | out[0] = 0x18; | |
61 | ||
62 | /* store values */ | |
63 | x = 2; | |
64 | STORE_V4(gtime->YYYY); | |
65 | STORE_V(gtime->MM); | |
66 | STORE_V(gtime->DD); | |
67 | STORE_V(gtime->hh); | |
68 | STORE_V(gtime->mm); | |
69 | STORE_V(gtime->ss); | |
70 | ||
71 | if (gtime->fs) { | |
72 | unsigned long divisor; | |
73 | unsigned fs = gtime->fs; | |
74 | unsigned len = 0; | |
75 | out[x++] = der_ia5_char_encode('.'); | |
76 | divisor = 1; | |
77 | do { | |
78 | fs /= 10; | |
79 | divisor *= 10; | |
80 | len++; | |
81 | } while(fs != 0); | |
82 | while (len-- > 1) { | |
83 | divisor /= 10; | |
84 | out[x++] = der_ia5_char_encode(baseten[(gtime->fs/divisor) % 10]); | |
85 | } | |
86 | out[x++] = der_ia5_char_encode(baseten[gtime->fs % 10]); | |
87 | } | |
88 | ||
89 | if (gtime->off_mm || gtime->off_hh) { | |
90 | out[x++] = der_ia5_char_encode(gtime->off_dir ? '-' : '+'); | |
91 | STORE_V(gtime->off_hh); | |
92 | STORE_V(gtime->off_mm); | |
93 | } else { | |
94 | out[x++] = der_ia5_char_encode('Z'); | |
95 | } | |
96 | ||
97 | /* store length */ | |
98 | out[1] = (unsigned char)(x - 2); | |
99 | ||
100 | /* all good let's return */ | |
101 | *outlen = x; | |
102 | return CRYPT_OK; | |
103 | } | |
104 | ||
105 | #endif | |
106 | ||
107 | /* $Source$ */ | |
108 | /* $Revision$ */ | |
109 | /* $Date$ */ |
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 | * Tom St Denis, tomstdenis@gmail.com, http://libtom.org | |
9 | */ | |
10 | #include "tomcrypt.h" | |
11 | ||
12 | /** | |
13 | @file der_length_utctime.c | |
14 | ASN.1 DER, get length of GeneralizedTime, Steffen Jaeckel | |
15 | Based on der_length_utctime.c | |
16 | */ | |
17 | ||
18 | #ifdef LTC_DER | |
19 | ||
20 | /** | |
21 | Gets length of DER encoding of GeneralizedTime | |
22 | @param utctime The UTC time structure to get the size of | |
23 | @param outlen [out] The length of the DER encoding | |
24 | @return CRYPT_OK if successful | |
25 | */ | |
26 | int der_length_generalizedtime(ltc_generalizedtime *gtime, unsigned long *outlen) | |
27 | { | |
28 | LTC_ARGCHK(outlen != NULL); | |
29 | LTC_ARGCHK(gtime != NULL); | |
30 | ||
31 | if (gtime->fs == 0) { | |
32 | /* we encode as YYYYMMDDhhmmssZ */ | |
33 | *outlen = 2 + 14 + 1; | |
34 | } else { | |
35 | unsigned long len = 2 + 14 + 1; | |
36 | unsigned fs = gtime->fs; | |
37 | do { | |
38 | fs /= 10; | |
39 | len++; | |
40 | } while(fs != 0); | |
41 | if (gtime->off_hh == 0 && gtime->off_mm == 0) { | |
42 | /* we encode as YYYYMMDDhhmmss.fsZ */ | |
43 | len += 1; | |
44 | } | |
45 | else { | |
46 | /* we encode as YYYYMMDDhhmmss.fs{+|-}hh'mm' */ | |
47 | len += 5; | |
48 | } | |
49 | *outlen = len; | |
50 | } | |
51 | ||
52 | return CRYPT_OK; | |
53 | } | |
54 | ||
55 | #endif | |
56 | ||
57 | /* $Source$ */ | |
58 | /* $Revision$ */ | |
59 | /* $Date$ */ |
258 | 258 | } |
259 | 259 | break; |
260 | 260 | |
261 | case LTC_ASN1_GENERALIZEDTIME: | |
262 | z = inlen; | |
263 | if ((err = der_decode_generalizedtime(in + x, &z, data)) != CRYPT_OK) { | |
264 | if (!ordered) { continue; } | |
265 | goto LBL_ERR; | |
266 | } | |
267 | break; | |
268 | ||
261 | 269 | case LTC_ASN1_SET: |
262 | 270 | z = inlen; |
263 | 271 | if ((err = der_decode_set(in + x, z, data, size)) != CRYPT_OK) { |
50 | 50 | ++in; |
51 | 51 | } |
52 | 52 | return z+*data_offset; |
53 | } | |
54 | ||
55 | static int new_element(ltc_asn1_list **l) | |
56 | { | |
57 | /* alloc new link */ | |
58 | if (*l == NULL) { | |
59 | *l = XCALLOC(1, sizeof(ltc_asn1_list)); | |
60 | if (*l == NULL) { | |
61 | return CRYPT_MEM; | |
62 | } | |
63 | } else { | |
64 | (*l)->next = XCALLOC(1, sizeof(ltc_asn1_list)); | |
65 | if ((*l)->next == NULL) { | |
66 | return CRYPT_MEM; | |
67 | } | |
68 | (*l)->next->prev = *l; | |
69 | *l = (*l)->next; | |
70 | } | |
71 | return CRYPT_OK; | |
53 | 72 | } |
54 | 73 | |
55 | 74 | /** |
72 | 91 | l = NULL; |
73 | 92 | totlen = 0; |
74 | 93 | |
94 | if (*inlen == 0) { | |
95 | /* alloc new link */ | |
96 | if ((err = new_element(&l)) != CRYPT_OK) { | |
97 | goto error; | |
98 | } | |
99 | } | |
100 | ||
75 | 101 | /* scan the input and and get lengths and what not */ |
76 | 102 | while (*inlen) { |
77 | 103 | /* read the type byte */ |
85 | 111 | } |
86 | 112 | |
87 | 113 | /* alloc new link */ |
88 | if (l == NULL) { | |
89 | l = XCALLOC(1, sizeof(*l)); | |
90 | if (l == NULL) { | |
91 | err = CRYPT_MEM; | |
92 | goto error; | |
93 | } | |
94 | } else { | |
95 | l->next = XCALLOC(1, sizeof(*l)); | |
96 | if (l->next == NULL) { | |
97 | err = CRYPT_MEM; | |
98 | goto error; | |
99 | } | |
100 | l->next->prev = l; | |
101 | l = l->next; | |
114 | if ((err = new_element(&l)) != CRYPT_OK) { | |
115 | goto error; | |
102 | 116 | } |
103 | 117 | |
104 | 118 | if ((type & 0x20) && (type != 0x30) && (type != 0x31)) { |
332 | 346 | } |
333 | 347 | break; |
334 | 348 | |
349 | case 0x18: | |
350 | l->type = LTC_ASN1_GENERALIZEDTIME; | |
351 | l->size = len; | |
352 | ||
353 | if ((l->data = XCALLOC(1, sizeof(ltc_generalizedtime))) == NULL) { | |
354 | err = CRYPT_MEM; | |
355 | goto error; | |
356 | } | |
357 | ||
358 | if ((err = der_decode_generalizedtime(in, &len, l->data)) != CRYPT_OK) { | |
359 | goto error; | |
360 | } | |
361 | ||
362 | if ((err = der_length_generalizedtime(l->data, &len)) != CRYPT_OK) { | |
363 | goto error; | |
364 | } | |
365 | ||
366 | break; | |
367 | ||
335 | 368 | case 0x20: /* Any CONSTRUCTED element that is neither SEQUENCE nor SET */ |
336 | 369 | case 0x30: /* SEQUENCE */ |
337 | 370 | case 0x31: /* SET */ |
346 | 379 | else { |
347 | 380 | l->type = LTC_ASN1_SET; |
348 | 381 | } |
382 | ||
383 | if ((l->data = XMALLOC(len)) == NULL) { | |
384 | err = CRYPT_MEM; | |
385 | goto error; | |
386 | } | |
387 | ||
388 | XMEMCPY(l->data, in, len); | |
389 | l->size = len; | |
390 | ||
349 | 391 | |
350 | 392 | /* jump to the start of the data */ |
351 | 393 | in += data_offset; |
68 | 68 | case LTC_ASN1_CHOICE: |
69 | 69 | case LTC_ASN1_RAW_BIT_STRING: |
70 | 70 | case LTC_ASN1_TELETEX_STRING: |
71 | case LTC_ASN1_GENERALIZEDTIME: | |
71 | 72 | ++x; |
72 | 73 | break; |
73 | 74 | |
120 | 121 | case LTC_ASN1_CHOICE: |
121 | 122 | case LTC_ASN1_RAW_BIT_STRING: |
122 | 123 | case LTC_ASN1_TELETEX_STRING: |
124 | case LTC_ASN1_GENERALIZEDTIME: | |
123 | 125 | LTC_SET_ASN1(list, x++, type, data, size); |
124 | 126 | break; |
125 | 127 | /* coverity[dead_error_line] */ |
165 | 165 | } |
166 | 166 | break; |
167 | 167 | |
168 | case LTC_ASN1_GENERALIZEDTIME: | |
169 | z = *outlen; | |
170 | if ((err = der_encode_generalizedtime(data, out + x, &z)) != CRYPT_OK) { | |
171 | goto LBL_ERR; | |
172 | } | |
173 | break; | |
174 | ||
168 | 175 | case LTC_ASN1_SET: |
169 | 176 | z = *outlen; |
170 | 177 | if ((err = der_encode_set(data, size, out + x, &z)) != CRYPT_OK) { |
191 | 198 | case LTC_ASN1_CONTEXT_SPECIFIC: |
192 | 199 | case LTC_ASN1_EOL: |
193 | 200 | case LTC_ASN1_TELETEX_STRING: |
194 | default: | |
195 | 201 | err = CRYPT_INVALID_ARG; |
196 | 202 | goto LBL_ERR; |
197 | 203 | } |
218 | 224 | tmptag[4] = (unsigned char)(z&255); |
219 | 225 | y = 5; |
220 | 226 | } |
221 | memmove(out + x + y, out + x, z); | |
222 | memcpy(out + x, tmptag, y); | |
227 | XMEMMOVE(out + x + y, out + x, z); | |
228 | XMEMCPY(out + x, tmptag, y); | |
223 | 229 | |
224 | 230 | z += y; |
225 | 231 | } |
67 | 67 | case LTC_ASN1_SET: |
68 | 68 | case LTC_ASN1_SETOF: |
69 | 69 | case LTC_ASN1_RAW_BIT_STRING: |
70 | case LTC_ASN1_GENERALIZEDTIME: | |
70 | 71 | ++x; |
71 | 72 | break; |
72 | 73 | |
119 | 120 | case LTC_ASN1_SET: |
120 | 121 | case LTC_ASN1_SETOF: |
121 | 122 | case LTC_ASN1_RAW_BIT_STRING: |
123 | case LTC_ASN1_GENERALIZEDTIME: | |
122 | 124 | LTC_SET_ASN1(list, x++, type, data, size); |
123 | 125 | break; |
124 | 126 |
125 | 125 | |
126 | 126 | case LTC_ASN1_UTCTIME: |
127 | 127 | if ((err = der_length_utctime(data, &x)) != CRYPT_OK) { |
128 | goto LBL_ERR; | |
129 | } | |
130 | y += x; | |
131 | break; | |
132 | ||
133 | case LTC_ASN1_GENERALIZEDTIME: | |
134 | if ((err = der_length_generalizedtime(data, &x)) != CRYPT_OK) { | |
128 | 135 | goto LBL_ERR; |
129 | 136 | } |
130 | 137 | y += x; |
45 | 45 | } |
46 | 46 | |
47 | 47 | switch (in->type) { |
48 | case LTC_ASN1_SET: | |
49 | case LTC_ASN1_SETOF: | |
50 | case LTC_ASN1_SEQUENCE: break; | |
48 | case LTC_ASN1_SETOF: break; | |
51 | 49 | case LTC_ASN1_INTEGER : if (in->data != NULL) { mp_clear(in->data); } break; |
52 | 50 | default : if (in->data != NULL) { XFREE(in->data); } |
53 | 51 | } |
33 | 33 | case LTC_ASN1_TELETEX_STRING: return 0x14; |
34 | 34 | case LTC_ASN1_IA5_STRING: return 0x16; |
35 | 35 | case LTC_ASN1_UTCTIME: return 0x17; |
36 | case LTC_ASN1_GENERALIZEDTIME: return 0x18; | |
36 | 37 | case LTC_ASN1_SEQUENCE: return 0x30; |
37 | 38 | case LTC_ASN1_SET: |
38 | 39 | case LTC_ASN1_SETOF: return 0x31; |
65 | 65 | |
66 | 66 | /* base point - we export uncompressed form */ |
67 | 67 | len_g = sizeof(bin_g); |
68 | if ((err = ecc_export_point(bin_g, &len_g, gx, gy, key->dp->size, 0)) != CRYPT_OK) goto error; | |
68 | if ((err = ltc_ecc_export_point(bin_g, &len_g, gx, gy, key->dp->size, 0)) != CRYPT_OK) goto error; | |
69 | 69 | |
70 | 70 | /* public key */ |
71 | 71 | len_xy = sizeof(bin_xy); |
72 | if ((err = ecc_export_point(bin_xy, &len_xy, key->pubkey.x, key->pubkey.y, key->dp->size, 0)) != CRYPT_OK) goto error; | |
72 | if ((err = ltc_ecc_export_point(bin_xy, &len_xy, key->pubkey.x, key->pubkey.y, key->dp->size, 0)) != CRYPT_OK) goto error; | |
73 | 73 | |
74 | 74 | /* co-factor */ |
75 | 75 | cofactor = key->dp->cofactor; |
14 | 14 | #include "tomcrypt.h" |
15 | 15 | |
16 | 16 | #ifdef LTC_MECC |
17 | ||
18 | int ecc_export_point(unsigned char *out, unsigned long *outlen, void *x, void *y, unsigned long size, int compressed) | |
19 | { | |
20 | int err; | |
21 | unsigned char buf[ECC_BUF_SIZE]; | |
22 | unsigned long xsize, ysize; | |
23 | ||
24 | if (size > sizeof(buf)) return CRYPT_BUFFER_OVERFLOW; | |
25 | if ((xsize = mp_unsigned_bin_size(x)) > size) return CRYPT_BUFFER_OVERFLOW; | |
26 | if ((ysize = mp_unsigned_bin_size(y)) > size) return CRYPT_BUFFER_OVERFLOW; | |
27 | ||
28 | if(compressed) { | |
29 | if (*outlen < (1 + size)) { | |
30 | *outlen = 1 + size; | |
31 | return CRYPT_BUFFER_OVERFLOW; | |
32 | } | |
33 | /* store first byte */ | |
34 | out[0] = mp_isodd(y) ? 0x03 : 0x02; | |
35 | /* pad and store x */ | |
36 | zeromem(buf, sizeof(buf)); | |
37 | if ((err = mp_to_unsigned_bin(x, buf + (size - xsize))) != CRYPT_OK) return err; | |
38 | XMEMCPY(out+1, buf, size); | |
39 | /* adjust outlen */ | |
40 | *outlen = 1 + size; | |
41 | } | |
42 | else { | |
43 | if (*outlen < (1 + 2*size)) { | |
44 | *outlen = 1 + 2*size; | |
45 | return CRYPT_BUFFER_OVERFLOW; | |
46 | } | |
47 | /* store byte 0x04 */ | |
48 | out[0] = 0x04; | |
49 | /* pad and store x */ | |
50 | zeromem(buf, sizeof(buf)); | |
51 | if ((err = mp_to_unsigned_bin(x, buf + (size - xsize))) != CRYPT_OK) return err; | |
52 | XMEMCPY(out+1, buf, size); | |
53 | /* pad and store y */ | |
54 | zeromem(buf, sizeof(buf)); | |
55 | if ((err = mp_to_unsigned_bin(y, buf + (size - ysize))) != CRYPT_OK) return err; | |
56 | XMEMCPY(out+1+size, buf, size); | |
57 | /* adjust outlen */ | |
58 | *outlen = 1 + 2*size; | |
59 | } | |
60 | return CRYPT_OK; | |
61 | } | |
62 | 17 | |
63 | 18 | /** Export raw public or private key (public keys = ANS X9.63 compressed or uncompressed; private keys = raw bytes) |
64 | 19 | @param out [out] destination of export |
83 | 38 | size = key->dp->size; |
84 | 39 | |
85 | 40 | if (type == PK_PUBLIC_COMPRESSED) { |
86 | if ((err = ecc_export_point(out, outlen, key->pubkey.x, key->pubkey.y, size, 1)) != CRYPT_OK) return err; | |
41 | if ((err = ltc_ecc_export_point(out, outlen, key->pubkey.x, key->pubkey.y, size, 1)) != CRYPT_OK) return err; | |
87 | 42 | } |
88 | 43 | else if (type == PK_PUBLIC) { |
89 | if ((err = ecc_export_point(out, outlen, key->pubkey.x, key->pubkey.y, size, 0)) != CRYPT_OK) return err; | |
44 | if ((err = ltc_ecc_export_point(out, outlen, key->pubkey.x, key->pubkey.y, size, 0)) != CRYPT_OK) return err; | |
90 | 45 | } |
91 | 46 | else if (type == PK_PRIVATE) { |
92 | 47 | if (key->type != PK_PRIVATE) return CRYPT_PK_TYPE_MISMATCH; |
66 | 66 | len_b = seq_curve[1].size; |
67 | 67 | len_g = seq_ecparams[3].size; |
68 | 68 | /* create bignums */ |
69 | if ((err = mp_read_unsigned_bin(a, bin_a, len_a)) != CRYPT_OK) { goto error; } | |
70 | if ((err = mp_read_unsigned_bin(b, bin_b, len_b)) != CRYPT_OK) { goto error; } | |
71 | if ((err = ecc_import_point(bin_g, len_g, prime, a, b, gx, gy)) != CRYPT_OK) { goto error; } | |
69 | if ((err = mp_read_unsigned_bin(a, bin_a, len_a)) != CRYPT_OK) { goto error; } | |
70 | if ((err = mp_read_unsigned_bin(b, bin_b, len_b)) != CRYPT_OK) { goto error; } | |
71 | if ((err = ltc_ecc_import_point(bin_g, len_g, prime, a, b, gx, gy)) != CRYPT_OK) { goto error; } | |
72 | 72 | /* load curve parameters */ |
73 | 73 | if ((err = ecc_dp_set_bn(dp, a, b, prime, order, gx, gy, cofactor)) != CRYPT_OK) { goto error; } |
74 | 74 | /* load public key */ |
75 | if ((err = ecc_import_raw(bin_xy, len_xy, key, dp)) != CRYPT_OK) { goto error; } | |
75 | if ((err = ecc_import_raw(bin_xy, len_xy, key, dp)) != CRYPT_OK) { goto error; } | |
76 | 76 | goto success; |
77 | 77 | } |
78 | 78 | |
130 | 130 | len_b = seq_curve[1].size; |
131 | 131 | len_g = seq_ecparams[3].size; |
132 | 132 | /* create bignums */ |
133 | if ((err = mp_read_unsigned_bin(a, bin_a, len_a)) != CRYPT_OK) { goto error; } | |
134 | if ((err = mp_read_unsigned_bin(b, bin_b, len_b)) != CRYPT_OK) { goto error; } | |
135 | if ((err = ecc_import_point(bin_g, len_g, prime, a, b, gx, gy)) != CRYPT_OK) { goto error; } | |
133 | if ((err = mp_read_unsigned_bin(a, bin_a, len_a)) != CRYPT_OK) { goto error; } | |
134 | if ((err = mp_read_unsigned_bin(b, bin_b, len_b)) != CRYPT_OK) { goto error; } | |
135 | if ((err = ltc_ecc_import_point(bin_g, len_g, prime, a, b, gx, gy)) != CRYPT_OK) { goto error; } | |
136 | 136 | /* load curve parameters */ |
137 | 137 | if ((err = ecc_dp_set_bn(dp, a, b, prime, order, gx, gy, cofactor)) != CRYPT_OK) { goto error; } |
138 | 138 | /* load private+public key */ |
139 | if ((err = ecc_import_raw(bin_k, len_k, key, dp)) != CRYPT_OK) { goto error; } | |
139 | if ((err = ecc_import_raw(bin_k, len_k, key, dp)) != CRYPT_OK) { goto error; } | |
140 | 140 | goto success; |
141 | 141 | } |
142 | 142 | |
143 | 143 | /* ### 5. backward compatibility - try to load old-DER format */ |
144 | if ((err = ecc_import(in, inlen, key)) != CRYPT_OK) { goto error; } | |
144 | if ((err = ecc_import(in, inlen, key)) != CRYPT_OK) { goto error; } | |
145 | 145 | |
146 | 146 | success: |
147 | 147 | err = CRYPT_OK; |
16 | 16 | |
17 | 17 | #ifdef LTC_MECC |
18 | 18 | |
19 | int ecc_import_pkcs8(unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp) | |
19 | int ecc_import_pkcs8(const unsigned char *in, unsigned long inlen, | |
20 | const void *pwd, unsigned long pwdlen, | |
21 | ecc_key *key, ltc_ecc_set_type *dp) | |
20 | 22 | { |
21 | 23 | int err; |
22 | 24 | void *zero, *one, *iter; |
63 | 65 | LTC_SET_ASN1(top_seq_e, 1, LTC_ASN1_OCTET_STRING, buf2, buf2len); |
64 | 66 | err=der_decode_sequence(in, inlen, top_seq_e, 2UL); |
65 | 67 | if (err == CRYPT_OK) { |
68 | LTC_UNUSED_PARAM(pwd); | |
69 | LTC_UNUSED_PARAM(pwdlen); | |
66 | 70 | /* unsigned long icount = mp_get_int(iter); */ |
67 | 71 | /* XXX: TODO decrypt buf1 with a key derived form password + salt + iter */ |
68 | 72 | /* fprintf(stderr, "XXX-DEBUG: gonna decrypt: iter=%ld salt.len=%ld encdata.len=%ld\n", icount, key_seq_e[0].size, top_seq_e[1].size); */ |
70 | 74 | goto LBL_ERR; |
71 | 75 | } |
72 | 76 | else { |
73 | decrypted = in; | |
77 | decrypted = (unsigned char*)in; | |
74 | 78 | decryptedlen = inlen; |
75 | 79 | } |
76 | 80 | |
118 | 122 | /* create bignums */ |
119 | 123 | if ((err = mp_read_unsigned_bin(a, bin_a, len_a)) != CRYPT_OK) { goto LBL_ERR; } |
120 | 124 | if ((err = mp_read_unsigned_bin(b, bin_b, len_b)) != CRYPT_OK) { goto LBL_ERR; } |
121 | if ((err = ecc_import_point(bin_g, len_g, prime, a, b, gx, gy)) != CRYPT_OK) { goto LBL_ERR; } | |
125 | if ((err = ltc_ecc_import_point(bin_g, len_g, prime, a, b, gx, gy)) != CRYPT_OK) { goto LBL_ERR; } | |
122 | 126 | /* load curve parameters */ |
123 | 127 | if ((err = ecc_dp_set_bn(dp, a, b, prime, order, gx, gy, cofactor)) != CRYPT_OK) { goto LBL_ERR; } |
124 | 128 | } |
14 | 14 | #include "tomcrypt.h" |
15 | 15 | |
16 | 16 | #ifdef LTC_MECC |
17 | ||
18 | int ecc_import_point(const unsigned char *in, unsigned long inlen, void *prime, void *a, void *b, void *x, void *y) | |
19 | { | |
20 | int err; | |
21 | unsigned long size; | |
22 | void *t1, *t2; | |
23 | ||
24 | /* init key + temporary numbers */ | |
25 | if (mp_init_multi(&t1, &t2, NULL) != CRYPT_OK) { | |
26 | return CRYPT_MEM; | |
27 | } | |
28 | ||
29 | size = mp_unsigned_bin_size(prime); | |
30 | ||
31 | if (in[0] == 0x04 && (inlen&1) && ((inlen-1)>>1) == size) { | |
32 | /* read uncompressed point */ | |
33 | /* load x */ | |
34 | if ((err = mp_read_unsigned_bin(x, (unsigned char *)in+1, size)) != CRYPT_OK) { goto cleanup; } | |
35 | /* load y */ | |
36 | if ((err = mp_read_unsigned_bin(y, (unsigned char *)in+1+size, size)) != CRYPT_OK) { goto cleanup; } | |
37 | } | |
38 | else if ((in[0] == 0x02 || in[0] == 0x03) && (inlen-1) == size) { | |
39 | /* read compressed point */ | |
40 | /* load x */ | |
41 | if ((err = mp_read_unsigned_bin(x, (unsigned char *)in+1, size)) != CRYPT_OK) { goto cleanup; } | |
42 | /* compute x^3 */ | |
43 | if ((err = mp_sqr(x, t1)) != CRYPT_OK) { goto cleanup; } | |
44 | if ((err = mp_mulmod(t1, x, prime, t1)) != CRYPT_OK) { goto cleanup; } | |
45 | /* compute x^3 + a*x */ | |
46 | if ((err = mp_mulmod(a, x, prime, t2)) != CRYPT_OK) { goto cleanup; } | |
47 | if ((err = mp_add(t1, t2, t1)) != CRYPT_OK) { goto cleanup; } | |
48 | /* compute x^3 + a*x + b */ | |
49 | if ((err = mp_add(t1, b, t1)) != CRYPT_OK) { goto cleanup; } | |
50 | /* compute sqrt(x^3 + a*x + b) */ | |
51 | if ((err = mp_sqrtmod_prime(t1, prime, t2)) != CRYPT_OK) { goto cleanup; } | |
52 | /* adjust y */ | |
53 | if ((mp_isodd(t2) && in[0] == 0x03) || (!mp_isodd(t2) && in[0] == 0x02)) { | |
54 | if ((err = mp_mod(t2, prime, y)) != CRYPT_OK) { goto cleanup; } | |
55 | } | |
56 | else { | |
57 | if ((err = mp_submod(prime, t2, prime, y)) != CRYPT_OK) { goto cleanup; } | |
58 | } | |
59 | } | |
60 | else { | |
61 | err = CRYPT_INVALID_PACKET; | |
62 | goto cleanup; | |
63 | } | |
64 | ||
65 | err = CRYPT_OK; | |
66 | cleanup: | |
67 | mp_clear_multi(t1, t2, NULL); | |
68 | return err; | |
69 | } | |
70 | 17 | |
71 | 18 | /** Import raw public or private key (public keys = ANSI X9.63 compressed or uncompressed; private keys = raw bytes) |
72 | 19 | @param in The input data to read |
127 | 74 | if ((err = mp_read_radix(prime, dp->prime, 16)) != CRYPT_OK) { goto cleanup; } |
128 | 75 | if ((err = mp_read_radix(b, dp->B, 16)) != CRYPT_OK) { goto cleanup; } |
129 | 76 | if ((err = mp_read_radix(a, dp->A, 16)) != CRYPT_OK) { goto cleanup; } |
130 | err = ecc_import_point(in, inlen, prime, a, b, key->pubkey.x, key->pubkey.y); | |
77 | err = ltc_ecc_import_point(in, inlen, prime, a, b, key->pubkey.x, key->pubkey.y); | |
131 | 78 | if (err != CRYPT_OK) { goto cleanup; } |
132 | 79 | if ((err = mp_set(key->pubkey.z, 1)) != CRYPT_OK) { goto cleanup; } |
133 | 80 | } |
26 | 26 | int *stat, ecc_key *key, int sigformat) |
27 | 27 | { |
28 | 28 | ecc_point *mG, *mQ; |
29 | void *r, *s, *v, *w, *u1, *u2, *e, *p, *m, *a; | |
29 | void *r, *s, *v, *w, *u1, *u2, *e, *p, *m, *a, *mu, *ma; | |
30 | 30 | void *mp; |
31 | 31 | int err; |
32 | 32 | unsigned long pbits, pbytes, i, shift_right; |
47 | 47 | } |
48 | 48 | |
49 | 49 | /* allocate ints */ |
50 | if ((err = mp_init_multi(&r, &s, &v, &w, &u1, &u2, &p, &e, &m, &a, NULL)) != CRYPT_OK) { | |
50 | if ((err = mp_init_multi(&r, &s, &v, &w, &u1, &u2, &p, &e, &m, &a, &mu, &ma, NULL)) != CRYPT_OK) { | |
51 | 51 | return CRYPT_MEM; |
52 | 52 | } |
53 | 53 | |
136 | 136 | |
137 | 137 | /* find the montgomery mp */ |
138 | 138 | if ((err = mp_montgomery_setup(m, &mp)) != CRYPT_OK) { goto error; } |
139 | if ((err = mp_montgomery_normalization(mu, m)) != CRYPT_OK) { goto error; } | |
140 | if ((err = mp_mulmod(a, mu, m, ma)) != CRYPT_OK) { goto error; } | |
139 | 141 | |
140 | 142 | /* add them */ |
141 | if ((err = ltc_mp.ecc_ptadd(mQ, mG, mG, a, m, mp)) != CRYPT_OK) { goto error; } | |
143 | if ((err = ltc_mp.ecc_ptadd(mQ, mG, mG, ma, m, mp)) != CRYPT_OK) { goto error; } | |
142 | 144 | |
143 | 145 | /* reduce */ |
144 | 146 | if ((err = ltc_mp.ecc_map(mG, m, mp)) != CRYPT_OK) { goto error; } |
160 | 162 | error: |
161 | 163 | ltc_ecc_del_point(mG); |
162 | 164 | ltc_ecc_del_point(mQ); |
163 | mp_clear_multi(r, s, v, w, u1, u2, p, e, m, a, NULL); | |
165 | mp_clear_multi(r, s, v, w, u1, u2, p, e, m, a, mu, ma, NULL); | |
164 | 166 | if (mp != NULL) { |
165 | 167 | mp_montgomery_free(mp); |
166 | 168 | } |
25 | 25 | |
26 | 26 | int ecc_verify_key(ecc_key *key) |
27 | 27 | { |
28 | int err; | |
29 | void *prime = NULL; | |
30 | void *order = NULL; | |
31 | void *a = NULL; | |
32 | ecc_point *test_output = NULL; | |
33 | test_output = malloc(sizeof(ecc_point)); | |
28 | int err; | |
29 | void *prime = NULL; | |
30 | void *order = NULL; | |
31 | void *a = NULL; | |
32 | ecc_point *point; | |
34 | 33 | |
35 | if (mp_init_multi(&(test_output->x), &(test_output->y), &(test_output->z), &order, &prime, NULL) != CRYPT_OK) { | |
36 | return CRYPT_MEM; | |
37 | } | |
34 | if (mp_init_multi(&order, &prime, NULL) != CRYPT_OK) { | |
35 | return CRYPT_MEM; | |
36 | } | |
38 | 37 | |
39 | /* Test 1: Are the x amd y points of the public key in the field? */ | |
40 | if((err = ltc_mp.read_radix(prime, key->dp->prime, 16)) != CRYPT_OK) { goto error;} | |
38 | /* Test 1: Are the x amd y points of the public key in the field? */ | |
39 | if ((err = ltc_mp.read_radix(prime, key->dp->prime, 16)) != CRYPT_OK) { goto done2; } | |
41 | 40 | |
42 | if(ltc_mp.compare_d(key->pubkey.z, 1) == LTC_MP_EQ) { | |
43 | if( | |
44 | (ltc_mp.compare(key->pubkey.x, prime) != LTC_MP_LT) | |
45 | || (ltc_mp.compare(key->pubkey.y, prime) != LTC_MP_LT) | |
46 | || (ltc_mp.compare_d(key->pubkey.x, 0) != LTC_MP_GT) | |
47 | || (ltc_mp.compare_d(key->pubkey.y, 0) != LTC_MP_GT) ) | |
41 | if (ltc_mp.compare_d(key->pubkey.z, 1) == LTC_MP_EQ) { | |
42 | if ((ltc_mp.compare(key->pubkey.x, prime) != LTC_MP_LT) || | |
43 | (ltc_mp.compare(key->pubkey.y, prime) != LTC_MP_LT) || | |
44 | (ltc_mp.compare_d(key->pubkey.x, 0) != LTC_MP_GT) || | |
45 | (ltc_mp.compare_d(key->pubkey.y, 0) != LTC_MP_GT) | |
46 | ) | |
48 | 47 | { |
49 | err = CRYPT_INVALID_PACKET; | |
50 | goto error; | |
48 | err = CRYPT_INVALID_PACKET; | |
49 | goto done2; | |
51 | 50 | } |
52 | } | |
51 | } | |
53 | 52 | |
54 | /* Test 2: is the public key on the curve? */ | |
55 | if((err = ltc_ecc_is_point(key->dp, key->pubkey.x, key->pubkey.y)) != CRYPT_OK) { goto error;} | |
53 | /* Test 2: is the public key on the curve? */ | |
54 | if ((err = ltc_ecc_is_point(key->dp, key->pubkey.x, key->pubkey.y)) != CRYPT_OK) { goto done2; } | |
56 | 55 | |
57 | /* Test 3: does nG = O? (n = order, 0 = point at infinity, G = public key) */ | |
58 | if((err = ltc_mp.read_radix(order, key->dp->order, 16)) != CRYPT_OK) { goto error;} | |
59 | if((err = ltc_mp.read_radix(a, key->dp->A, 16)) != CRYPT_OK) { goto error;} | |
60 | if((err = ltc_ecc_mulmod(order, &(key->pubkey), test_output, a, prime, 1)) != CRYPT_OK) { | |
61 | goto error; | |
62 | } | |
56 | /* Test 3: does nG = O? (n = order, O = point at infinity, G = public key) */ | |
57 | point = ltc_ecc_new_point(); | |
58 | if ((err = ltc_mp.read_radix(order, key->dp->order, 16)) != CRYPT_OK) { goto done1; } | |
59 | if ((err = ltc_mp.read_radix(a, key->dp->A, 16)) != CRYPT_OK) { goto done1; } | |
60 | if ((err = ltc_ecc_mulmod(order, &(key->pubkey), point, a, prime, 1)) != CRYPT_OK) { goto done1; } | |
63 | 61 | |
64 | err = CRYPT_OK; | |
65 | error: | |
66 | mp_clear_multi(prime, order, test_output->z, test_output->y, test_output->x, NULL); | |
67 | return err; | |
62 | if (ltc_ecc_is_point_at_infinity(point, prime)) { | |
63 | err = CRYPT_ERROR; | |
64 | } | |
65 | else { | |
66 | err = CRYPT_OK; | |
67 | } | |
68 | ||
69 | done1: | |
70 | ltc_ecc_del_point(point); | |
71 | done2: | |
72 | mp_clear_multi(prime, order, NULL); | |
73 | return err; | |
68 | 74 | } |
69 | 75 | |
70 | 76 | #endif |
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 | */ | |
9 | ||
10 | /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b | |
11 | * | |
12 | */ | |
13 | ||
14 | #include "tomcrypt.h" | |
15 | ||
16 | #ifdef LTC_MECC | |
17 | ||
18 | int ltc_ecc_export_point(unsigned char *out, unsigned long *outlen, void *x, void *y, unsigned long size, int compressed) | |
19 | { | |
20 | int err; | |
21 | unsigned char buf[ECC_BUF_SIZE]; | |
22 | unsigned long xsize, ysize; | |
23 | ||
24 | if (size > sizeof(buf)) return CRYPT_BUFFER_OVERFLOW; | |
25 | if ((xsize = mp_unsigned_bin_size(x)) > size) return CRYPT_BUFFER_OVERFLOW; | |
26 | if ((ysize = mp_unsigned_bin_size(y)) > size) return CRYPT_BUFFER_OVERFLOW; | |
27 | ||
28 | if(compressed) { | |
29 | if (*outlen < (1 + size)) { | |
30 | *outlen = 1 + size; | |
31 | return CRYPT_BUFFER_OVERFLOW; | |
32 | } | |
33 | /* store first byte */ | |
34 | out[0] = mp_isodd(y) ? 0x03 : 0x02; | |
35 | /* pad and store x */ | |
36 | zeromem(buf, sizeof(buf)); | |
37 | if ((err = mp_to_unsigned_bin(x, buf + (size - xsize))) != CRYPT_OK) return err; | |
38 | XMEMCPY(out+1, buf, size); | |
39 | /* adjust outlen */ | |
40 | *outlen = 1 + size; | |
41 | } | |
42 | else { | |
43 | if (*outlen < (1 + 2*size)) { | |
44 | *outlen = 1 + 2*size; | |
45 | return CRYPT_BUFFER_OVERFLOW; | |
46 | } | |
47 | /* store byte 0x04 */ | |
48 | out[0] = 0x04; | |
49 | /* pad and store x */ | |
50 | zeromem(buf, sizeof(buf)); | |
51 | if ((err = mp_to_unsigned_bin(x, buf + (size - xsize))) != CRYPT_OK) return err; | |
52 | XMEMCPY(out+1, buf, size); | |
53 | /* pad and store y */ | |
54 | zeromem(buf, sizeof(buf)); | |
55 | if ((err = mp_to_unsigned_bin(y, buf + (size - ysize))) != CRYPT_OK) return err; | |
56 | XMEMCPY(out+1+size, buf, size); | |
57 | /* adjust outlen */ | |
58 | *outlen = 1 + 2*size; | |
59 | } | |
60 | return CRYPT_OK; | |
61 | } | |
62 | ||
63 | #endif |
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 | */ | |
9 | ||
10 | /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b | |
11 | * | |
12 | */ | |
13 | ||
14 | #include "tomcrypt.h" | |
15 | ||
16 | #ifdef LTC_MECC | |
17 | ||
18 | int ltc_ecc_import_point(const unsigned char *in, unsigned long inlen, void *prime, void *a, void *b, void *x, void *y) | |
19 | { | |
20 | int err; | |
21 | unsigned long size; | |
22 | void *t1, *t2; | |
23 | ||
24 | /* init key + temporary numbers */ | |
25 | if (mp_init_multi(&t1, &t2, NULL) != CRYPT_OK) { | |
26 | return CRYPT_MEM; | |
27 | } | |
28 | ||
29 | size = mp_unsigned_bin_size(prime); | |
30 | ||
31 | if (in[0] == 0x04 && (inlen&1) && ((inlen-1)>>1) == size) { | |
32 | /* read uncompressed point */ | |
33 | /* load x */ | |
34 | if ((err = mp_read_unsigned_bin(x, (unsigned char *)in+1, size)) != CRYPT_OK) { goto cleanup; } | |
35 | /* load y */ | |
36 | if ((err = mp_read_unsigned_bin(y, (unsigned char *)in+1+size, size)) != CRYPT_OK) { goto cleanup; } | |
37 | } | |
38 | else if ((in[0] == 0x02 || in[0] == 0x03) && (inlen-1) == size) { | |
39 | /* read compressed point */ | |
40 | /* load x */ | |
41 | if ((err = mp_read_unsigned_bin(x, (unsigned char *)in+1, size)) != CRYPT_OK) { goto cleanup; } | |
42 | /* compute x^3 */ | |
43 | if ((err = mp_sqr(x, t1)) != CRYPT_OK) { goto cleanup; } | |
44 | if ((err = mp_mulmod(t1, x, prime, t1)) != CRYPT_OK) { goto cleanup; } | |
45 | /* compute x^3 + a*x */ | |
46 | if ((err = mp_mulmod(a, x, prime, t2)) != CRYPT_OK) { goto cleanup; } | |
47 | if ((err = mp_add(t1, t2, t1)) != CRYPT_OK) { goto cleanup; } | |
48 | /* compute x^3 + a*x + b */ | |
49 | if ((err = mp_add(t1, b, t1)) != CRYPT_OK) { goto cleanup; } | |
50 | /* compute sqrt(x^3 + a*x + b) */ | |
51 | if ((err = mp_sqrtmod_prime(t1, prime, t2)) != CRYPT_OK) { goto cleanup; } | |
52 | /* adjust y */ | |
53 | if ((mp_isodd(t2) && in[0] == 0x03) || (!mp_isodd(t2) && in[0] == 0x02)) { | |
54 | if ((err = mp_mod(t2, prime, y)) != CRYPT_OK) { goto cleanup; } | |
55 | } | |
56 | else { | |
57 | if ((err = mp_submod(prime, t2, prime, y)) != CRYPT_OK) { goto cleanup; } | |
58 | } | |
59 | } | |
60 | else { | |
61 | err = CRYPT_INVALID_PACKET; | |
62 | goto cleanup; | |
63 | } | |
64 | ||
65 | err = CRYPT_OK; | |
66 | cleanup: | |
67 | mp_clear_multi(t1, t2, NULL); | |
68 | return err; | |
69 | } | |
70 | ||
71 | #endif |
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 | * Tom St Denis, tomstdenis@gmail.com, http://libtom.org | |
9 | */ | |
10 | ||
11 | #include "tomcrypt.h" | |
12 | ||
13 | #ifdef LTC_MECC | |
14 | ||
15 | /* http://crypto.stackexchange.com/questions/41468/point-at-infinity-for-jacobian-coordinates | |
16 | * a point at infinity is any point (x,y,0) such that y^2 == x^3, except (0,0,0) | |
17 | */ | |
18 | ||
19 | int ltc_ecc_is_point_at_infinity(ecc_point *P, void *modulus) | |
20 | { | |
21 | int err, retval = 0; | |
22 | void *x3, *y2; | |
23 | ||
24 | /* trivial case */ | |
25 | if (!mp_iszero(P->z)) goto done; | |
26 | ||
27 | /* point (0,0,0) is not at infinity */ | |
28 | if (mp_iszero(P->x) && mp_iszero(P->y)) goto done; | |
29 | ||
30 | /* initialize */ | |
31 | if ((err = mp_init_multi(&x3, &y2, NULL)) != CRYPT_OK) goto done; | |
32 | ||
33 | /* compute y^2 */ | |
34 | if ((err = mp_mulmod(P->y, P->y, modulus, y2)) != CRYPT_OK) goto cleanup; | |
35 | ||
36 | /* compute x^3 */ | |
37 | if ((err = mp_mulmod(P->x, P->x, modulus, x3)) != CRYPT_OK) goto cleanup; | |
38 | if ((err = mp_mulmod(P->x, x3, modulus, x3)) != CRYPT_OK) goto cleanup; | |
39 | ||
40 | /* test y^2 == x^3 */ | |
41 | if ((mp_cmp(x3, y2) == LTC_MP_EQ) && !mp_iszero(y2)) retval = 1; | |
42 | ||
43 | cleanup: | |
44 | mp_clear_multi(x3, y2, NULL); | |
45 | done: | |
46 | return retval; | |
47 | } | |
48 | ||
49 | #endif |
36 | 36 | LTC_ARGCHK(modulus != NULL); |
37 | 37 | LTC_ARGCHK(mp != NULL); |
38 | 38 | |
39 | if (mp_iszero(P->z)) { | |
40 | if ((err = mp_set(P->x, 0)) != CRYPT_OK) { return err; } | |
41 | if ((err = mp_set(P->y, 0)) != CRYPT_OK) { return err; } | |
42 | if ((err = mp_set(P->z, 1)) != CRYPT_OK) { return err; } | |
43 | return CRYPT_OK; | |
44 | } | |
45 | ||
39 | 46 | if ((err = mp_init_multi(&t1, &t2, NULL)) != CRYPT_OK) { |
40 | 47 | return CRYPT_MEM; |
41 | 48 | } |
42 | 42 | unsigned x, y; |
43 | 43 | unsigned char *tA, *tB; |
44 | 44 | int err, first; |
45 | void *mp, *mu; | |
45 | void *mp, *mu, *ma; | |
46 | 46 | |
47 | 47 | /* argchks */ |
48 | 48 | LTC_ARGCHK(A != NULL); |
96 | 96 | if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { |
97 | 97 | goto ERR_P; |
98 | 98 | } |
99 | if ((err = mp_init(&mu)) != CRYPT_OK) { | |
99 | if ((err = mp_init_multi(&mu, &ma, NULL)) != CRYPT_OK) { | |
100 | 100 | goto ERR_MP; |
101 | 101 | } |
102 | 102 | if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) { |
103 | goto ERR_MU; | |
104 | } | |
105 | if ((err = mp_mulmod(a, mu, modulus, ma)) != CRYPT_OK) { | |
103 | 106 | goto ERR_MU; |
104 | 107 | } |
105 | 108 | |
113 | 116 | if ((err = mp_mulmod(B->z, mu, modulus, precomp[1<<2]->z)) != CRYPT_OK) { goto ERR_MU; } |
114 | 117 | |
115 | 118 | /* precomp [i,0](A + B) table */ |
116 | if ((err = ltc_mp.ecc_ptdbl(precomp[1], precomp[2], a, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } | |
117 | if ((err = ltc_mp.ecc_ptadd(precomp[1], precomp[2], precomp[3], a, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } | |
119 | if ((err = ltc_mp.ecc_ptdbl(precomp[1], precomp[2], ma, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } | |
120 | if ((err = ltc_mp.ecc_ptadd(precomp[1], precomp[2], precomp[3], ma, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } | |
118 | 121 | |
119 | 122 | /* precomp [0,i](A + B) table */ |
120 | if ((err = ltc_mp.ecc_ptdbl(precomp[1<<2], precomp[2<<2], a, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } | |
121 | if ((err = ltc_mp.ecc_ptadd(precomp[1<<2], precomp[2<<2], precomp[3<<2], a, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } | |
123 | if ((err = ltc_mp.ecc_ptdbl(precomp[1<<2], precomp[2<<2], ma, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } | |
124 | if ((err = ltc_mp.ecc_ptadd(precomp[1<<2], precomp[2<<2], precomp[3<<2], ma, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } | |
122 | 125 | |
123 | 126 | /* precomp [i,j](A + B) table (i != 0, j != 0) */ |
124 | 127 | for (x = 1; x < 4; x++) { |
125 | 128 | for (y = 1; y < 4; y++) { |
126 | if ((err = ltc_mp.ecc_ptadd(precomp[x], precomp[(y<<2)], precomp[x+(y<<2)], a, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } | |
129 | if ((err = ltc_mp.ecc_ptadd(precomp[x], precomp[(y<<2)], precomp[x+(y<<2)], ma, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } | |
127 | 130 | } |
128 | 131 | } |
129 | 132 | |
157 | 160 | /* double twice, only if this isn't the first */ |
158 | 161 | if (first == 0) { |
159 | 162 | /* double twice */ |
160 | if ((err = ltc_mp.ecc_ptdbl(C, C, a, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } | |
161 | if ((err = ltc_mp.ecc_ptdbl(C, C, a, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } | |
163 | if ((err = ltc_mp.ecc_ptdbl(C, C, ma, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } | |
164 | if ((err = ltc_mp.ecc_ptdbl(C, C, ma, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } | |
162 | 165 | } |
163 | 166 | |
164 | 167 | /* if not both zero */ |
171 | 174 | if ((err = mp_copy(precomp[nA + (nB<<2)]->z, C->z)) != CRYPT_OK) { goto ERR_MU; } |
172 | 175 | } else { |
173 | 176 | /* if not first, add from table */ |
174 | if ((err = ltc_mp.ecc_ptadd(C, precomp[nA + (nB<<2)], C, a, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } | |
177 | if ((err = ltc_mp.ecc_ptadd(C, precomp[nA + (nB<<2)], C, ma, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } | |
175 | 178 | } |
176 | 179 | } |
177 | 180 | } |
181 | 184 | |
182 | 185 | /* clean up */ |
183 | 186 | ERR_MU: |
184 | mp_clear(mu); | |
187 | mp_clear_multi(mu, ma, NULL); | |
185 | 188 | ERR_MP: |
186 | 189 | mp_montgomery_free(mp); |
187 | 190 | ERR_P: |
37 | 37 | { |
38 | 38 | ecc_point *tG, *M[8]; |
39 | 39 | int i, j, err; |
40 | void *mu, *mp; | |
40 | void *mu, *mp, *ma; | |
41 | 41 | ltc_mp_digit buf; |
42 | 42 | int first, bitbuf, bitcpy, bitcnt, mode, digidx; |
43 | 43 | |
46 | 46 | LTC_ARGCHK(R != NULL); |
47 | 47 | LTC_ARGCHK(modulus != NULL); |
48 | 48 | |
49 | if (ltc_ecc_is_point_at_infinity(G, modulus)) { | |
50 | /* return the point at infinity */ | |
51 | if ((err = mp_set(R->x, 1)) != CRYPT_OK) { return err; } | |
52 | if ((err = mp_set(R->y, 1)) != CRYPT_OK) { return err; } | |
53 | if ((err = mp_set(R->z, 0)) != CRYPT_OK) { return err; } | |
54 | return CRYPT_OK; | |
55 | } | |
56 | ||
49 | 57 | /* init montgomery reduction */ |
50 | 58 | if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { |
51 | 59 | return err; |
52 | 60 | } |
53 | if ((err = mp_init(&mu)) != CRYPT_OK) { | |
61 | if ((err = mp_init_multi(&mu, &ma, NULL)) != CRYPT_OK) { | |
54 | 62 | mp_montgomery_free(mp); |
55 | 63 | return err; |
56 | 64 | } |
57 | 65 | if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) { |
58 | 66 | mp_montgomery_free(mp); |
59 | mp_clear(mu); | |
67 | mp_clear_multi(mu, ma, NULL); | |
68 | return err; | |
69 | } | |
70 | if ((err = mp_mulmod(a, mu, modulus, ma)) != CRYPT_OK) { | |
71 | mp_montgomery_free(mp); | |
72 | mp_clear_multi(mu, ma, NULL); | |
60 | 73 | return err; |
61 | 74 | } |
62 | 75 | |
68 | 81 | ltc_ecc_del_point(M[j]); |
69 | 82 | } |
70 | 83 | mp_montgomery_free(mp); |
71 | mp_clear(mu); | |
84 | mp_clear_multi(mu, ma, NULL); | |
72 | 85 | return CRYPT_MEM; |
73 | 86 | } |
74 | 87 | } |
92 | 105 | |
93 | 106 | /* calc the M tab, which holds kG for k==8..15 */ |
94 | 107 | /* M[0] == 8G */ |
95 | if ((err = ltc_mp.ecc_ptdbl(tG, M[0], a, modulus, mp)) != CRYPT_OK) { goto done; } | |
96 | if ((err = ltc_mp.ecc_ptdbl(M[0], M[0], a, modulus, mp)) != CRYPT_OK) { goto done; } | |
97 | if ((err = ltc_mp.ecc_ptdbl(M[0], M[0], a, modulus, mp)) != CRYPT_OK) { goto done; } | |
108 | if ((err = ltc_mp.ecc_ptdbl(tG, M[0], ma, modulus, mp)) != CRYPT_OK) { goto done; } | |
109 | if ((err = ltc_mp.ecc_ptdbl(M[0], M[0], ma, modulus, mp)) != CRYPT_OK) { goto done; } | |
110 | if ((err = ltc_mp.ecc_ptdbl(M[0], M[0], ma, modulus, mp)) != CRYPT_OK) { goto done; } | |
98 | 111 | |
99 | 112 | /* now find (8+k)G for k=1..7 */ |
100 | 113 | for (j = 9; j < 16; j++) { |
101 | if ((err = ltc_mp.ecc_ptadd(M[j-9], tG, M[j-8], a, modulus, mp)) != CRYPT_OK) { goto done; } | |
114 | if ((err = ltc_mp.ecc_ptadd(M[j-9], tG, M[j-8], ma, modulus, mp)) != CRYPT_OK) { goto done; } | |
102 | 115 | } |
103 | 116 | |
104 | 117 | /* setup sliding window */ |
132 | 145 | |
133 | 146 | /* if the bit is zero and mode == 1 then we double */ |
134 | 147 | if (mode == 1 && i == 0) { |
135 | if ((err = ltc_mp.ecc_ptdbl(R, R, a, modulus, mp)) != CRYPT_OK) { goto done; } | |
148 | if ((err = ltc_mp.ecc_ptdbl(R, R, ma, modulus, mp)) != CRYPT_OK) { goto done; } | |
136 | 149 | continue; |
137 | 150 | } |
138 | 151 | |
153 | 166 | /* ok window is filled so double as required and add */ |
154 | 167 | /* double first */ |
155 | 168 | for (j = 0; j < WINSIZE; j++) { |
156 | if ((err = ltc_mp.ecc_ptdbl(R, R, a, modulus, mp)) != CRYPT_OK) { goto done; } | |
169 | if ((err = ltc_mp.ecc_ptdbl(R, R, ma, modulus, mp)) != CRYPT_OK) { goto done; } | |
157 | 170 | } |
158 | 171 | |
159 | 172 | /* then add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */ |
160 | if ((err = ltc_mp.ecc_ptadd(R, M[bitbuf-8], R, a, modulus, mp)) != CRYPT_OK) { goto done; } | |
173 | if ((err = ltc_mp.ecc_ptadd(R, M[bitbuf-8], R, ma, modulus, mp)) != CRYPT_OK) { goto done; } | |
161 | 174 | } |
162 | 175 | /* empty window and reset */ |
163 | 176 | bitcpy = bitbuf = 0; |
171 | 184 | for (j = 0; j < bitcpy; j++) { |
172 | 185 | /* only double if we have had at least one add first */ |
173 | 186 | if (first == 0) { |
174 | if ((err = ltc_mp.ecc_ptdbl(R, R, a, modulus, mp)) != CRYPT_OK) { goto done; } | |
187 | if ((err = ltc_mp.ecc_ptdbl(R, R, ma, modulus, mp)) != CRYPT_OK) { goto done; } | |
175 | 188 | } |
176 | 189 | |
177 | 190 | bitbuf <<= 1; |
184 | 197 | first = 0; |
185 | 198 | } else { |
186 | 199 | /* then add */ |
187 | if ((err = ltc_mp.ecc_ptadd(R, tG, R, a, modulus, mp)) != CRYPT_OK) { goto done; } | |
200 | if ((err = ltc_mp.ecc_ptadd(R, tG, R, ma, modulus, mp)) != CRYPT_OK) { goto done; } | |
188 | 201 | } |
189 | 202 | } |
190 | 203 | } |
200 | 213 | if (mu != NULL) { |
201 | 214 | mp_clear(mu); |
202 | 215 | } |
216 | mp_clear(ma); | |
203 | 217 | mp_montgomery_free(mp); |
204 | 218 | ltc_ecc_del_point(tG); |
205 | 219 | for (i = 0; i < 8; i++) { |
36 | 36 | { |
37 | 37 | ecc_point *tG, *M[3]; |
38 | 38 | int i, j, err; |
39 | void *mu, *mp; | |
39 | void *mu, *mp, *ma; | |
40 | 40 | ltc_mp_digit buf; |
41 | 41 | int bitcnt, mode, digidx; |
42 | 42 | |
45 | 45 | LTC_ARGCHK(R != NULL); |
46 | 46 | LTC_ARGCHK(modulus != NULL); |
47 | 47 | |
48 | if (ltc_ecc_is_point_at_infinity(G, modulus)) { | |
49 | /* return the point at infinity */ | |
50 | if ((err = mp_set(R->x, 1)) != CRYPT_OK) { return err; } | |
51 | if ((err = mp_set(R->y, 1)) != CRYPT_OK) { return err; } | |
52 | if ((err = mp_set(R->z, 0)) != CRYPT_OK) { return err; } | |
53 | return CRYPT_OK; | |
54 | } | |
55 | ||
48 | 56 | /* init montgomery reduction */ |
49 | 57 | if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { |
50 | 58 | return err; |
51 | 59 | } |
52 | if ((err = mp_init(&mu)) != CRYPT_OK) { | |
60 | if ((err = mp_init_multi(&mu, &ma, NULL)) != CRYPT_OK) { | |
53 | 61 | mp_montgomery_free(mp); |
54 | 62 | return err; |
55 | 63 | } |
56 | 64 | if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) { |
57 | 65 | mp_clear(mu); |
58 | 66 | mp_montgomery_free(mp); |
67 | return err; | |
68 | } | |
69 | if ((err = mp_mulmod(a, mu, modulus, ma)) != CRYPT_OK) { | |
70 | mp_montgomery_free(mp); | |
71 | mp_clear_multi(mu, ma, NULL); | |
59 | 72 | return err; |
60 | 73 | } |
61 | 74 | |
89 | 102 | if ((err = mp_copy(tG->y, M[0]->y)) != CRYPT_OK) { goto done; } |
90 | 103 | if ((err = mp_copy(tG->z, M[0]->z)) != CRYPT_OK) { goto done; } |
91 | 104 | /* M[1] == 2G */ |
92 | if ((err = ltc_mp.ecc_ptdbl(tG, M[1], a, modulus, mp)) != CRYPT_OK) { goto done; } | |
105 | if ((err = ltc_mp.ecc_ptdbl(tG, M[1], ma, modulus, mp)) != CRYPT_OK) { goto done; } | |
93 | 106 | |
94 | 107 | /* setup sliding window */ |
95 | 108 | mode = 0; |
115 | 128 | |
116 | 129 | if (mode == 0 && i == 0) { |
117 | 130 | /* dummy operations */ |
118 | if ((err = ltc_mp.ecc_ptadd(M[0], M[1], M[2], a, modulus, mp)) != CRYPT_OK) { goto done; } | |
119 | if ((err = ltc_mp.ecc_ptdbl(M[1], M[2], a, modulus, mp)) != CRYPT_OK) { goto done; } | |
131 | if ((err = ltc_mp.ecc_ptadd(M[0], M[1], M[2], ma, modulus, mp)) != CRYPT_OK) { goto done; } | |
132 | if ((err = ltc_mp.ecc_ptdbl(M[1], M[2], ma, modulus, mp)) != CRYPT_OK) { goto done; } | |
120 | 133 | continue; |
121 | 134 | } |
122 | 135 | |
123 | 136 | if (mode == 0 && i == 1) { |
124 | 137 | mode = 1; |
125 | 138 | /* dummy operations */ |
126 | if ((err = ltc_mp.ecc_ptadd(M[0], M[1], M[2], a, modulus, mp)) != CRYPT_OK) { goto done; } | |
127 | if ((err = ltc_mp.ecc_ptdbl(M[1], M[2], a, modulus, mp)) != CRYPT_OK) { goto done; } | |
139 | if ((err = ltc_mp.ecc_ptadd(M[0], M[1], M[2], ma, modulus, mp)) != CRYPT_OK) { goto done; } | |
140 | if ((err = ltc_mp.ecc_ptdbl(M[1], M[2], ma, modulus, mp)) != CRYPT_OK) { goto done; } | |
128 | 141 | continue; |
129 | 142 | } |
130 | 143 | |
131 | if ((err = ltc_mp.ecc_ptadd(M[0], M[1], M[i^1], a, modulus, mp)) != CRYPT_OK) { goto done; } | |
132 | if ((err = ltc_mp.ecc_ptdbl(M[i], M[i], a, modulus, mp)) != CRYPT_OK) { goto done; } | |
144 | if ((err = ltc_mp.ecc_ptadd(M[0], M[1], M[i^1], ma, modulus, mp)) != CRYPT_OK) { goto done; } | |
145 | if ((err = ltc_mp.ecc_ptdbl(M[i], M[i], ma, modulus, mp)) != CRYPT_OK) { goto done; } | |
133 | 146 | } |
134 | 147 | |
135 | 148 | /* copy result out */ |
147 | 160 | if (mu != NULL) { |
148 | 161 | mp_clear(mu); |
149 | 162 | } |
163 | mp_clear(ma); | |
150 | 164 | mp_montgomery_free(mp); |
151 | 165 | ltc_ecc_del_point(tG); |
152 | 166 | for (i = 0; i < 3; i++) { |
25 | 25 | @param P The point to add |
26 | 26 | @param Q The point to add |
27 | 27 | @param R [out] The destination of the double |
28 | @param ma ECC curve parameter a in montgomery form (if NULL we assume a == -3) | |
28 | 29 | @param modulus The modulus of the field the ECC curve is in |
29 | 30 | @param mp The "b" value from montgomery_setup() |
30 | 31 | @return CRYPT_OK on success |
31 | 32 | */ |
32 | int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *a, void *modulus, void *mp) | |
33 | int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *ma, void *modulus, void *mp) | |
33 | 34 | { |
34 | 35 | void *t1, *t2, *x, *y, *z; |
35 | 36 | int err; |
44 | 45 | return err; |
45 | 46 | } |
46 | 47 | |
47 | /* should we dbl instead? */ | |
48 | if ((err = mp_sub(modulus, Q->y, t1)) != CRYPT_OK) { goto done; } | |
49 | ||
50 | if ( (mp_cmp(P->x, Q->x) == LTC_MP_EQ) && | |
51 | (Q->z != NULL && mp_cmp(P->z, Q->z) == LTC_MP_EQ) && | |
52 | (mp_cmp(P->y, Q->y) == LTC_MP_EQ || mp_cmp(P->y, t1) == LTC_MP_EQ)) { | |
53 | mp_clear_multi(t1, t2, x, y, z, NULL); | |
54 | return ltc_ecc_projective_dbl_point(P, R, a, modulus, mp); | |
48 | if (ltc_ecc_is_point_at_infinity(P, modulus)) { | |
49 | /* P is point at infinity >> Result = Q */ | |
50 | if ((err = ltc_mp.copy(Q->x, R->x)) != CRYPT_OK) { goto done; } | |
51 | if ((err = ltc_mp.copy(Q->y, R->y)) != CRYPT_OK) { goto done; } | |
52 | if ((err = ltc_mp.copy(Q->z, R->z)) != CRYPT_OK) { goto done; } | |
53 | goto done; /* CRYPT_OK */ | |
54 | } | |
55 | ||
56 | if (ltc_ecc_is_point_at_infinity(Q, modulus)) { | |
57 | /* Q is point at infinity >> Result = P */ | |
58 | if ((err = ltc_mp.copy(P->x, R->x)) != CRYPT_OK) { goto done; } | |
59 | if ((err = ltc_mp.copy(P->y, R->y)) != CRYPT_OK) { goto done; } | |
60 | if ((err = ltc_mp.copy(P->z, R->z)) != CRYPT_OK) { goto done; } | |
61 | goto done; /* CRYPT_OK */ | |
62 | } | |
63 | ||
64 | if ((mp_cmp(P->x, Q->x) == LTC_MP_EQ) && (mp_cmp(P->z, Q->z) == LTC_MP_EQ)) { | |
65 | if (mp_cmp(P->y, Q->y) == LTC_MP_EQ) { | |
66 | /* here P = Q >> Result = 2 * P (use doubling) */ | |
67 | mp_clear_multi(t1, t2, x, y, z, NULL); | |
68 | return ltc_ecc_projective_dbl_point(P, R, ma, modulus, mp); | |
69 | } | |
70 | if ((err = mp_sub(modulus, Q->y, t1)) != CRYPT_OK) { goto done; } | |
71 | if (mp_cmp(P->y, t1) == LTC_MP_EQ) { | |
72 | /* here Q = -P >>> Result = the point at infinity */ | |
73 | if ((err = ltc_mp.set_int(R->x, 1)) != CRYPT_OK) { goto done; } | |
74 | if ((err = ltc_mp.set_int(R->y, 1)) != CRYPT_OK) { goto done; } | |
75 | if ((err = ltc_mp.set_int(R->z, 0)) != CRYPT_OK) { goto done; } | |
76 | goto done; /* CRYPT_OK */ | |
77 | } | |
55 | 78 | } |
56 | 79 | |
57 | 80 | if ((err = mp_copy(P->x, x)) != CRYPT_OK) { goto done; } |
42 | 42 | Double an ECC point |
43 | 43 | @param P The point to double |
44 | 44 | @param R [out] The destination of the double |
45 | @param a ECC curve parameter a (if NULL we assume a == -3) | |
45 | @param ma ECC curve parameter a in montgomery form (if NULL we assume a == -3) | |
46 | 46 | @param modulus The modulus of the field the ECC curve is in |
47 | 47 | @param mp The "b" value from montgomery_setup() |
48 | 48 | @return CRYPT_OK on success |
49 | 49 | */ |
50 | int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *a, void *modulus, void *mp) | |
50 | int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *ma, void *modulus, void *mp) | |
51 | 51 | { |
52 | 52 | void *t1, *t2; |
53 | 53 | int err; |
65 | 65 | if ((err = mp_copy(P->x, R->x)) != CRYPT_OK) { goto done; } |
66 | 66 | if ((err = mp_copy(P->y, R->y)) != CRYPT_OK) { goto done; } |
67 | 67 | if ((err = mp_copy(P->z, R->z)) != CRYPT_OK) { goto done; } |
68 | } | |
69 | ||
70 | if (ltc_ecc_is_point_at_infinity(P, modulus)) { | |
71 | /* if P is point at infinity >> Result = point at infinity */ | |
72 | if ((err = ltc_mp.set_int(R->x, 1)) != CRYPT_OK) { goto done; } | |
73 | if ((err = ltc_mp.set_int(R->y, 1)) != CRYPT_OK) { goto done; } | |
74 | if ((err = ltc_mp.set_int(R->z, 0)) != CRYPT_OK) { goto done; } | |
75 | goto done; /* CRYPT_OK */ | |
68 | 76 | } |
69 | 77 | |
70 | 78 | /* t1 = Z * Z */ |
79 | 87 | if ((err = mp_sub(R->z, modulus, R->z)) != CRYPT_OK) { goto done; } |
80 | 88 | } |
81 | 89 | |
82 | if (a == NULL) { /* special case for a == -3 (slightly faster than general case) */ | |
90 | if (ma == NULL) { /* special case for ma == -3 (slightly faster than general case) */ | |
83 | 91 | /* T2 = X - T1 */ |
84 | 92 | if ((err = mp_sub(R->x, t1, t2)) != CRYPT_OK) { goto done; } |
85 | 93 | if (mp_cmp_d(t2, 0) == LTC_MP_LT) { |
109 | 117 | if ((err = mp_sqr(t1, t2)) != CRYPT_OK) { goto done; } |
110 | 118 | if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; } |
111 | 119 | /* T1 = T2 * a */ |
112 | if ((err = mp_mulmod(t2, a, modulus, t1)) != CRYPT_OK) { goto done; } | |
120 | if ((err = mp_mul(t2, ma, t1)) != CRYPT_OK) { goto done; } | |
121 | if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; } | |
113 | 122 | /* T2 = X * X */ |
114 | 123 | if ((err = mp_sqr(R->x, t2)) != CRYPT_OK) { goto done; } |
115 | 124 | if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; } |
23 | 23 | void rsa_free(rsa_key *key) |
24 | 24 | { |
25 | 25 | LTC_ARGCHKVD(key != NULL); |
26 | mp_clear_multi(key->e, key->d, key->N, key->dQ, key->dP, key->qP, key->p, key->q, NULL); | |
26 | mp_clear_multi(key->q, key->p, key->qP, key->dP, key->dQ, key->N, key->d, key->e, NULL); | |
27 | 27 | } |
28 | 28 | |
29 | 29 | #endif |
41 | 41 | |
42 | 42 | /** |
43 | 43 | Import an RSAPublicKey or RSAPrivateKey in PKCS#8 format |
44 | @param in The packet to import from | |
45 | @param inlen It's length (octets) | |
46 | @param key [out] Destination for newly imported key | |
44 | @param in The packet to import from | |
45 | @param inlen It's length (octets) | |
46 | @param passwd The password for decrypting privkey (NOT SUPPORTED YET) | |
47 | @param passwdlen Password's length (octets) | |
48 | @param key [out] Destination for newly imported key | |
47 | 49 | @return CRYPT_OK if successful, upon error allocated memory is freed |
48 | 50 | */ |
49 | int rsa_import_pkcs8(const unsigned char *in, unsigned long inlen, rsa_key *key) | |
51 | int rsa_import_pkcs8(const unsigned char *in, unsigned long inlen, | |
52 | const void *passwd, unsigned long passwdlen, | |
53 | rsa_key *key) | |
50 | 54 | { |
51 | 55 | int err; |
52 | 56 | void *zero, *iter; |
88 | 92 | LTC_SET_ASN1(top_seq_e, 1, LTC_ASN1_OCTET_STRING, buf2, buf2len); |
89 | 93 | err=der_decode_sequence(in, inlen, top_seq_e, 2UL); |
90 | 94 | if (err == CRYPT_OK) { |
91 | /* XXX: TODO encrypted pkcs8 not supported */ | |
95 | LTC_UNUSED_PARAM(passwd); | |
96 | LTC_UNUSED_PARAM(passwdlen); | |
97 | /* XXX: TODO encrypted pkcs8 not implemented yet */ | |
92 | 98 | /* fprintf(stderr, "decrypt: iter=%ld salt.len=%ld encdata.len=%ld\n", mp_get_int(iter), key_seq_e[0].size, top_seq_e[1].size); */ |
93 | 99 | err = CRYPT_PK_INVALID_TYPE; |
94 | 100 | goto LBL_ERR; |
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 | * Tom St Denis, tomstdenis@gmail.com, http://libtom.org | |
9 | */ | |
10 | #include "tomcrypt.h" | |
11 | ||
12 | /** | |
13 | @file rsa_import.c | |
14 | Import an RSA key from a X.509 certificate, Steffen Jaeckel | |
15 | */ | |
16 | ||
17 | #ifdef LTC_MRSA | |
18 | ||
19 | /** | |
20 | Import an RSA key from a X.509 certificate | |
21 | @param in The packet to import from | |
22 | @param inlen It's length (octets) | |
23 | @param key [out] Destination for newly imported key | |
24 | @return CRYPT_OK if successful, upon error allocated memory is freed | |
25 | */ | |
26 | int rsa_import_x509(const unsigned char *in, unsigned long inlen, rsa_key *key) | |
27 | { | |
28 | int err; | |
29 | unsigned char *tmpbuf=NULL; | |
30 | unsigned long tmpbuf_len, tmp_inlen; | |
31 | ltc_asn1_list *decoded_list = NULL, *l; | |
32 | ||
33 | LTC_ARGCHK(in != NULL); | |
34 | LTC_ARGCHK(key != NULL); | |
35 | LTC_ARGCHK(ltc_mp.name != NULL); | |
36 | ||
37 | /* init key */ | |
38 | if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, | |
39 | &key->dP, &key->qP, &key->p, &key->q, NULL)) != CRYPT_OK) { | |
40 | return err; | |
41 | } | |
42 | ||
43 | tmpbuf_len = MAX_RSA_SIZE * 8; | |
44 | tmpbuf = XCALLOC(1, tmpbuf_len); | |
45 | if (tmpbuf == NULL) { | |
46 | err = CRYPT_MEM; | |
47 | goto LBL_ERR; | |
48 | } | |
49 | ||
50 | tmp_inlen = inlen; | |
51 | if ((err = der_decode_sequence_flexi(in, &tmp_inlen, &decoded_list)) == CRYPT_OK) { | |
52 | l = decoded_list; | |
53 | /* Move 2 levels up in the tree | |
54 | SEQUENCE | |
55 | SEQUENCE | |
56 | ... | |
57 | */ | |
58 | if (l->type == LTC_ASN1_SEQUENCE && l->child) { | |
59 | l = l->child; | |
60 | if (l->type == LTC_ASN1_SEQUENCE && l->child) { | |
61 | l = l->child; | |
62 | ||
63 | err = CRYPT_ERROR; | |
64 | ||
65 | /* Move forward in the tree until we find this combination | |
66 | ... | |
67 | SEQUENCE | |
68 | SEQUENCE | |
69 | OBJECT IDENTIFIER 1.2.840.113549.1.1.1 | |
70 | NULL | |
71 | BIT STRING | |
72 | */ | |
73 | do { | |
74 | /* The additional check for l->data is there to make sure | |
75 | * we won't try to decode a list that has been 'shrunk' | |
76 | */ | |
77 | if (l->type == LTC_ASN1_SEQUENCE && l->data && l->child && | |
78 | l->child->type == LTC_ASN1_SEQUENCE && l->child->child && | |
79 | l->child->child->type == LTC_ASN1_OBJECT_IDENTIFIER && l->child->next && | |
80 | l->child->next->type == LTC_ASN1_BIT_STRING) { | |
81 | err = der_decode_subject_public_key_info(l->data, l->size, | |
82 | PKA_RSA, tmpbuf, &tmpbuf_len, | |
83 | LTC_ASN1_NULL, NULL, 0); | |
84 | if (err == CRYPT_OK) { | |
85 | /* now it should be SEQUENCE { INTEGER, INTEGER } */ | |
86 | if ((err = der_decode_sequence_multi(tmpbuf, tmpbuf_len, | |
87 | LTC_ASN1_INTEGER, 1UL, key->N, | |
88 | LTC_ASN1_INTEGER, 1UL, key->e, | |
89 | LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { | |
90 | goto LBL_ERR; | |
91 | } | |
92 | key->type = PK_PUBLIC; | |
93 | err = CRYPT_OK; | |
94 | goto LBL_FREE; | |
95 | } | |
96 | } | |
97 | l = l->next; | |
98 | } while(l); | |
99 | } | |
100 | } | |
101 | } | |
102 | ||
103 | ||
104 | LBL_ERR: | |
105 | rsa_free(key); | |
106 | ||
107 | LBL_FREE: | |
108 | if (decoded_list) der_free_sequence_flexi(decoded_list); | |
109 | if (tmpbuf != NULL) XFREE(tmpbuf); | |
110 | ||
111 | return err; | |
112 | } | |
113 | ||
114 | #endif /* LTC_MRSA */ | |
115 | ||
116 | ||
117 | /* $Source$ */ | |
118 | /* $Revision$ */ | |
119 | /* $Date$ */ |
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 | ||
9 | /* the idea of re-keying loosely follows the approach used in: | |
10 | * http://bxr.su/OpenBSD/lib/libc/crypt/arc4random.c | |
11 | */ | |
12 | ||
13 | #include "tomcrypt.h" | |
14 | ||
15 | #ifdef LTC_CHACHA20_PRNG | |
16 | ||
17 | const struct ltc_prng_descriptor chacha20_prng_desc = | |
18 | { | |
19 | "chacha", | |
20 | sizeof(chacha_state), | |
21 | &chacha20_prng_start, | |
22 | &chacha20_prng_add_entropy, | |
23 | &chacha20_prng_ready, | |
24 | &chacha20_prng_read, | |
25 | &chacha20_prng_done, | |
26 | &chacha20_prng_export, | |
27 | &chacha20_prng_import, | |
28 | &chacha20_prng_test | |
29 | }; | |
30 | ||
31 | /** | |
32 | Start the PRNG | |
33 | @param prng[out] The PRNG state to initialize | |
34 | @return CRYPT_OK if successful | |
35 | */ | |
36 | int chacha20_prng_start(prng_state *prng) | |
37 | { | |
38 | LTC_ARGCHK(prng != NULL); | |
39 | prng->chacha.ready = 0; | |
40 | XMEMSET(&prng->chacha.ent, 0, 40); | |
41 | prng->chacha.idx = 0; | |
42 | return CRYPT_OK; | |
43 | } | |
44 | ||
45 | /** | |
46 | Add entropy to the PRNG state | |
47 | @param in The data to add | |
48 | @param inlen Length of the data to add | |
49 | @param prng PRNG state to update | |
50 | @return CRYPT_OK if successful | |
51 | */ | |
52 | int chacha20_prng_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng) | |
53 | { | |
54 | unsigned char buf[40]; | |
55 | unsigned long i; | |
56 | int err; | |
57 | ||
58 | LTC_ARGCHK(prng != NULL); | |
59 | LTC_ARGCHK(in != NULL); | |
60 | LTC_ARGCHK(inlen > 0); | |
61 | ||
62 | if (prng->chacha.ready) { | |
63 | /* chacha20_prng_ready() was already called, do "rekey" operation */ | |
64 | if ((err = chacha_keystream(&prng->chacha.s, buf, 40)) != CRYPT_OK) return err; | |
65 | for(i = 0; i < inlen; i++) buf[i % 40] ^= in[i]; | |
66 | /* key 32 bytes, 20 rounds */ | |
67 | if ((err = chacha_setup(&prng->chacha.s, buf, 32, 20)) != CRYPT_OK) return err; | |
68 | /* iv 8 bytes */ | |
69 | if ((err = chacha_ivctr64(&prng->chacha.s, buf + 32, 8, 0)) != CRYPT_OK) return err; | |
70 | /* clear KEY + IV */ | |
71 | XMEMSET(buf, 0, 40); | |
72 | } | |
73 | else { | |
74 | /* chacha20_prng_ready() was not called yet, add entropy to ent buffer */ | |
75 | while (inlen--) prng->chacha.ent[prng->chacha.idx++ % 40] ^= *in++; | |
76 | } | |
77 | ||
78 | return CRYPT_OK; | |
79 | } | |
80 | ||
81 | /** | |
82 | Make the PRNG ready to read from | |
83 | @param prng The PRNG to make active | |
84 | @return CRYPT_OK if successful | |
85 | */ | |
86 | int chacha20_prng_ready(prng_state *prng) | |
87 | { | |
88 | int err; | |
89 | ||
90 | LTC_ARGCHK(prng != NULL); | |
91 | ||
92 | /* key 32 bytes, 20 rounds */ | |
93 | if ((err = chacha_setup(&prng->chacha.s, prng->chacha.ent, 32, 20)) != CRYPT_OK) return err; | |
94 | /* iv 8 bytes */ | |
95 | if ((err = chacha_ivctr64(&prng->chacha.s, prng->chacha.ent + 32, 8, 0)) != CRYPT_OK) return err; | |
96 | XMEMSET(&prng->chacha.ent, 0, 40); | |
97 | prng->chacha.ready = 1; | |
98 | prng->chacha.idx = 0; | |
99 | return CRYPT_OK; | |
100 | } | |
101 | ||
102 | /** | |
103 | Read from the PRNG | |
104 | @param out Destination | |
105 | @param outlen Length of output | |
106 | @param prng The active PRNG to read from | |
107 | @return Number of octets read | |
108 | */ | |
109 | unsigned long chacha20_prng_read(unsigned char *out, unsigned long outlen, prng_state *prng) | |
110 | { | |
111 | LTC_ARGCHK(prng != NULL); | |
112 | if (chacha_keystream(&prng->chacha.s, out, outlen) != CRYPT_OK) return 0; | |
113 | return outlen; | |
114 | } | |
115 | ||
116 | /** | |
117 | Terminate the PRNG | |
118 | @param prng The PRNG to terminate | |
119 | @return CRYPT_OK if successful | |
120 | */ | |
121 | int chacha20_prng_done(prng_state *prng) | |
122 | { | |
123 | LTC_ARGCHK(prng != NULL); | |
124 | return chacha_done(&prng->chacha.s); | |
125 | } | |
126 | ||
127 | /** | |
128 | Export the PRNG state | |
129 | @param out [out] Destination | |
130 | @param outlen [in/out] Max size and resulting size of the state | |
131 | @param prng The PRNG to export | |
132 | @return CRYPT_OK if successful | |
133 | */ | |
134 | int chacha20_prng_export(unsigned char *out, unsigned long *outlen, prng_state *prng) | |
135 | { | |
136 | unsigned long len = sizeof(chacha_state); | |
137 | LTC_ARGCHK(outlen != NULL); | |
138 | LTC_ARGCHK(out != NULL); | |
139 | LTC_ARGCHK(prng != NULL); | |
140 | ||
141 | if (!prng->chacha.ready) { | |
142 | return CRYPT_ERROR; | |
143 | } | |
144 | if (*outlen < len) { | |
145 | *outlen = len; | |
146 | return CRYPT_BUFFER_OVERFLOW; | |
147 | } | |
148 | XMEMCPY(out, &prng->chacha.s, len); | |
149 | *outlen = len; | |
150 | return CRYPT_OK; | |
151 | } | |
152 | ||
153 | /** | |
154 | Import a PRNG state | |
155 | @param in The PRNG state | |
156 | @param inlen Size of the state | |
157 | @param prng The PRNG to import | |
158 | @return CRYPT_OK if successful | |
159 | */ | |
160 | int chacha20_prng_import(const unsigned char *in, unsigned long inlen, prng_state *prng) | |
161 | { | |
162 | unsigned long len = sizeof(chacha_state); | |
163 | LTC_ARGCHK(in != NULL); | |
164 | LTC_ARGCHK(prng != NULL); | |
165 | ||
166 | if (inlen != len) return CRYPT_INVALID_ARG; | |
167 | XMEMCPY(&prng->chacha.s, in, inlen); | |
168 | prng->chacha.ready = 1; | |
169 | return CRYPT_OK; | |
170 | } | |
171 | ||
172 | /** | |
173 | PRNG self-test | |
174 | @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled | |
175 | */ | |
176 | int chacha20_prng_test(void) | |
177 | { | |
178 | #ifndef LTC_TEST | |
179 | return CRYPT_NOP; | |
180 | #else | |
181 | prng_state st; | |
182 | unsigned char en[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, | |
183 | 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, | |
184 | 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, | |
185 | 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, | |
186 | 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32 }; | |
187 | unsigned char dmp[300]; | |
188 | unsigned long dmplen = sizeof(dmp); | |
189 | unsigned char out[500]; | |
190 | unsigned char t1[] = { 0x59, 0xb2, 0x26, 0x95, 0x2b, 0x01, 0x8f, 0x05, 0xbe, 0xd8 }; | |
191 | unsigned char t2[] = { 0x30, 0x34, 0x5c, 0x6e, 0x56, 0x18, 0x8c, 0x46, 0xbe, 0x8a }; | |
192 | ||
193 | chacha20_prng_start(&st); | |
194 | chacha20_prng_add_entropy(en, sizeof(en), &st); /* add entropy to uninitialized prng */ | |
195 | chacha20_prng_ready(&st); | |
196 | chacha20_prng_read(out, 10, &st); /* 10 bytes for testing */ | |
197 | if (compare_testvector(out, 10, t1, sizeof(t1), "CHACHA-PRNG", 1)) return CRYPT_FAIL_TESTVECTOR; | |
198 | chacha20_prng_read(out, 500, &st); | |
199 | chacha20_prng_add_entropy(en, sizeof(en), &st); /* add entropy to already initialized prng */ | |
200 | chacha20_prng_read(out, 500, &st); | |
201 | chacha20_prng_export(dmp, &dmplen, &st); | |
202 | chacha20_prng_read(out, 500, &st); /* skip 500 bytes */ | |
203 | chacha20_prng_read(out, 10, &st); /* 10 bytes for testing */ | |
204 | if (compare_testvector(out, 10, t2, sizeof(t2), "CHACHA-PRNG", 2)) return CRYPT_FAIL_TESTVECTOR; | |
205 | chacha20_prng_done(&st); | |
206 | ||
207 | XMEMSET(&st, 0xFF, sizeof(st)); /* just to be sure */ | |
208 | chacha20_prng_import(dmp, dmplen, &st); | |
209 | chacha20_prng_read(out, 500, &st); /* skip 500 bytes */ | |
210 | chacha20_prng_read(out, 10, &st); /* 10 bytes for testing */ | |
211 | if (compare_testvector(out, 10, t2, sizeof(t2), "CHACHA-PRNG", 3)) return CRYPT_FAIL_TESTVECTOR; | |
212 | chacha20_prng_done(&st); | |
213 | ||
214 | return CRYPT_OK; | |
215 | #endif | |
216 | } | |
217 | ||
218 | #endif |
23 | 23 | &rc4_add_entropy, |
24 | 24 | &rc4_ready, |
25 | 25 | &rc4_read, |
26 | &rc4_done, | |
26 | &rc4_prng_done, | |
27 | 27 | &rc4_export, |
28 | 28 | &rc4_import, |
29 | &rc4_test | |
29 | &rc4_prng_test | |
30 | 30 | }; |
31 | 31 | |
32 | 32 | /** |
154 | 154 | @param prng The PRNG to terminate |
155 | 155 | @return CRYPT_OK if successful |
156 | 156 | */ |
157 | int rc4_done(prng_state *prng) | |
157 | int rc4_prng_done(prng_state *prng) | |
158 | 158 | { |
159 | 159 | LTC_ARGCHK(prng != NULL); |
160 | 160 | return CRYPT_OK; |
213 | 213 | PRNG self-test |
214 | 214 | @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled |
215 | 215 | */ |
216 | int rc4_test(void) | |
216 | int rc4_prng_test(void) | |
217 | 217 | { |
218 | 218 | #if !defined(LTC_TEST) || defined(LTC_VALGRIND) |
219 | 219 | return CRYPT_NOP; |
245 | 245 | if (rc4_read(dst, 8, &prng) != 8) { |
246 | 246 | return CRYPT_ERROR_READPRNG; |
247 | 247 | } |
248 | rc4_done(&prng); | |
248 | rc4_prng_done(&prng); | |
249 | 249 | if (XMEMCMP(dst, tests[x].ct, 8)) { |
250 | 250 | #if 0 |
251 | 251 | int y; |
134 | 134 | |
135 | 135 | LTC_ARGCHK(out != NULL); |
136 | 136 | |
137 | #ifdef LTC_PRNG_ENABLE_LTC_RNG | |
138 | if (ltc_rng) { | |
139 | x = ltc_rng(out, outlen, callback); | |
140 | if (x != 0) { | |
141 | return x; | |
142 | } | |
143 | } | |
144 | #endif | |
145 | ||
137 | 146 | #if defined(_WIN32) || defined(_WIN32_WCE) |
138 | 147 | x = rng_win32(out, outlen, callback); if (x != 0) { return x; } |
139 | 148 | #elif defined(LTC_DEVRANDOM) |
27 | 27 | &sober128_add_entropy, |
28 | 28 | &sober128_ready, |
29 | 29 | &sober128_read, |
30 | &sober128_done, | |
30 | &sober128_prng_done, | |
31 | 31 | &sober128_export, |
32 | 32 | &sober128_import, |
33 | &sober128_test | |
33 | &sober128_prng_test | |
34 | 34 | }; |
35 | 35 | |
36 | 36 | /* don't change these... */ |
364 | 364 | @param prng The PRNG to terminate |
365 | 365 | @return CRYPT_OK if successful |
366 | 366 | */ |
367 | int sober128_done(prng_state *prng) | |
367 | int sober128_prng_done(prng_state *prng) | |
368 | 368 | { |
369 | 369 | LTC_ARGCHK(prng != NULL); |
370 | 370 | return CRYPT_OK; |
426 | 426 | PRNG self-test |
427 | 427 | @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled |
428 | 428 | */ |
429 | int sober128_test(void) | |
429 | int sober128_prng_test(void) | |
430 | 430 | { |
431 | 431 | #ifndef LTC_TEST |
432 | 432 | return CRYPT_NOP; |
477 | 477 | if (sober128_read(dst, tests[x].len, &prng) != (unsigned long)tests[x].len) { |
478 | 478 | return CRYPT_ERROR_READPRNG; |
479 | 479 | } |
480 | sober128_done(&prng); | |
480 | sober128_prng_done(&prng); | |
481 | 481 | if (XMEMCMP(dst, tests[x].out, tests[x].len)) { |
482 | 482 | #if 0 |
483 | 483 | printf("\n\nLTC_SOBER128 failed, I got:\n"); |
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 | ||
9 | /* The implementation is based on: | |
10 | * chacha-ref.c version 20080118 | |
11 | * Public domain from D. J. Bernstein | |
12 | */ | |
13 | ||
14 | #include "tomcrypt.h" | |
15 | ||
16 | #ifdef LTC_CHACHA | |
17 | ||
18 | #define QUARTERROUND(a,b,c,d) \ | |
19 | x[a] += x[b]; x[d] = ROL(x[d] ^ x[a], 16); \ | |
20 | x[c] += x[d]; x[b] = ROL(x[b] ^ x[c], 12); \ | |
21 | x[a] += x[b]; x[d] = ROL(x[d] ^ x[a], 8); \ | |
22 | x[c] += x[d]; x[b] = ROL(x[b] ^ x[c], 7); | |
23 | ||
24 | static void _chacha_block(unsigned char *output, const ulong32 *input, int rounds) | |
25 | { | |
26 | ulong32 x[16]; | |
27 | int i; | |
28 | XMEMCPY(x, input, sizeof(x)); | |
29 | for (i = rounds; i > 0; i -= 2) { | |
30 | QUARTERROUND(0, 4, 8,12) | |
31 | QUARTERROUND(1, 5, 9,13) | |
32 | QUARTERROUND(2, 6,10,14) | |
33 | QUARTERROUND(3, 7,11,15) | |
34 | QUARTERROUND(0, 5,10,15) | |
35 | QUARTERROUND(1, 6,11,12) | |
36 | QUARTERROUND(2, 7, 8,13) | |
37 | QUARTERROUND(3, 4, 9,14) | |
38 | } | |
39 | for (i = 0; i < 16; ++i) { | |
40 | x[i] += input[i]; | |
41 | STORE32L(x[i], output + 4 * i); | |
42 | } | |
43 | } | |
44 | ||
45 | /** | |
46 | Encrypt (or decrypt) bytes of ciphertext (or plaintext) with ChaCha | |
47 | @param st The ChaCha state | |
48 | @param in The plaintext (or ciphertext) | |
49 | @param inlen The length of the input (octets) | |
50 | @param out [out] The ciphertext (or plaintext), length inlen | |
51 | @return CRYPT_OK if successful | |
52 | */ | |
53 | int chacha_crypt(chacha_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out) | |
54 | { | |
55 | unsigned char buf[64]; | |
56 | unsigned long i, j; | |
57 | ||
58 | if (inlen == 0) return CRYPT_OK; /* nothing to do */ | |
59 | LTC_ARGCHK(st != NULL); | |
60 | LTC_ARGCHK(in != NULL); | |
61 | LTC_ARGCHK(out != NULL); | |
62 | ||
63 | if (st->ksleft > 0) { | |
64 | j = MIN(st->ksleft, inlen); | |
65 | for (i = 0; i < j; ++i, st->ksleft--) out[i] = in[i] ^ st->kstream[64 - st->ksleft]; | |
66 | inlen -= j; | |
67 | if (inlen == 0) return CRYPT_OK; | |
68 | out += j; | |
69 | in += j; | |
70 | } | |
71 | for (;;) { | |
72 | _chacha_block(buf, st->input, st->rounds); | |
73 | /* increment the counter */ | |
74 | if (!++st->input[12] && !++st->input[13] && !++st->input[14]) { ++st->input[15]; } | |
75 | if (inlen <= 64) { | |
76 | for (i = 0; i < inlen; ++i) out[i] = in[i] ^ buf[i]; | |
77 | st->ksleft = 64 - inlen; | |
78 | for (i = inlen; i < 64; ++i) st->kstream[i] = buf[i]; | |
79 | return CRYPT_OK; | |
80 | } | |
81 | for (i = 0; i < 64; ++i) out[i] = in[i] ^ buf[i]; | |
82 | inlen -= 64; | |
83 | out += 64; | |
84 | in += 64; | |
85 | } | |
86 | return CRYPT_OK; | |
87 | }; | |
88 | ||
89 | #endif |
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 | ||
9 | #include "tomcrypt.h" | |
10 | ||
11 | #ifdef LTC_CHACHA | |
12 | ||
13 | /** | |
14 | Terminate and clear ChaCha state | |
15 | @param st The ChaCha state | |
16 | @return CRYPT_OK on success | |
17 | */ | |
18 | int chacha_done(chacha_state *st) | |
19 | { | |
20 | LTC_ARGCHK(st != NULL); | |
21 | XMEMSET(st, 0, sizeof(chacha_state)); | |
22 | return CRYPT_OK; | |
23 | }; | |
24 | ||
25 | #endif |
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 | ||
9 | /* The implementation is based on: | |
10 | * chacha-ref.c version 20080118 | |
11 | * Public domain from D. J. Bernstein | |
12 | */ | |
13 | ||
14 | #include "tomcrypt.h" | |
15 | ||
16 | #ifdef LTC_CHACHA | |
17 | ||
18 | /** | |
19 | Set IV + counter data to the ChaCha state | |
20 | @param st The ChaCha20 state | |
21 | @param iv The IV data to add | |
22 | @param inlen The length of the IV (must be 12) | |
23 | @param counter 32bit (unsigned) initial counter value | |
24 | @return CRYPT_OK on success | |
25 | */ | |
26 | int chacha_ivctr32(chacha_state *st, const unsigned char *iv, unsigned long ivlen, ulong32 counter) | |
27 | { | |
28 | LTC_ARGCHK(st != NULL); | |
29 | LTC_ARGCHK(iv != NULL); | |
30 | /* 96bit IV + 32bit counter */ | |
31 | LTC_ARGCHK(ivlen == 12); | |
32 | ||
33 | st->input[12] = counter; | |
34 | LOAD32L(st->input[13], iv + 0); | |
35 | LOAD32L(st->input[14], iv + 4); | |
36 | LOAD32L(st->input[15], iv + 8); | |
37 | st->ksleft = 0; | |
38 | return CRYPT_OK; | |
39 | }; | |
40 | ||
41 | #endif |
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 | ||
9 | /* The implementation is based on: | |
10 | * chacha-ref.c version 20080118 | |
11 | * Public domain from D. J. Bernstein | |
12 | */ | |
13 | ||
14 | #include "tomcrypt.h" | |
15 | ||
16 | #ifdef LTC_CHACHA | |
17 | ||
18 | /** | |
19 | Set IV + counter data to the ChaCha state | |
20 | @param st The ChaCha20 state | |
21 | @param iv The IV data to add | |
22 | @param inlen The length of the IV (must be 8) | |
23 | @param counter 64bit (unsigned) initial counter value | |
24 | @return CRYPT_OK on success | |
25 | */ | |
26 | int chacha_ivctr64(chacha_state *st, const unsigned char *iv, unsigned long ivlen, ulong64 counter) | |
27 | { | |
28 | LTC_ARGCHK(st != NULL); | |
29 | LTC_ARGCHK(iv != NULL); | |
30 | /* 64bit IV + 64bit counter */ | |
31 | LTC_ARGCHK(ivlen == 8); | |
32 | ||
33 | st->input[12] = (ulong32)(counter & 0xFFFFFFFF); | |
34 | st->input[13] = (ulong32)(counter >> 32); | |
35 | LOAD32L(st->input[14], iv + 0); | |
36 | LOAD32L(st->input[15], iv + 4); | |
37 | st->ksleft = 0; | |
38 | return CRYPT_OK; | |
39 | }; | |
40 | ||
41 | #endif |
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 | ||
9 | /* The implementation is based on: | |
10 | * chacha-ref.c version 20080118 | |
11 | * Public domain from D. J. Bernstein | |
12 | */ | |
13 | ||
14 | #include "tomcrypt.h" | |
15 | ||
16 | #ifdef LTC_CHACHA | |
17 | ||
18 | /** | |
19 | Generate a stream of random bytes via ChaCha | |
20 | @param st The ChaCha20 state | |
21 | @param out [out] The output buffer | |
22 | @param outlen The output length | |
23 | @return CRYPT_OK on success | |
24 | */ | |
25 | int chacha_keystream(chacha_state *st, unsigned char *out, unsigned long outlen) | |
26 | { | |
27 | if (outlen == 0) return CRYPT_OK; /* nothing to do */ | |
28 | LTC_ARGCHK(out != NULL); | |
29 | XMEMSET(out, 0, outlen); | |
30 | return chacha_crypt(st, out, outlen, out); | |
31 | } | |
32 | ||
33 | #endif |
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 | ||
9 | /* The implementation is based on: | |
10 | * chacha-ref.c version 20080118 | |
11 | * Public domain from D. J. Bernstein | |
12 | */ | |
13 | ||
14 | #include "tomcrypt.h" | |
15 | ||
16 | #ifdef LTC_CHACHA | |
17 | ||
18 | static const char sigma[16] = "expand 32-byte k"; | |
19 | static const char tau[16] = "expand 16-byte k"; | |
20 | ||
21 | /** | |
22 | Initialize an ChaCha context (only the key) | |
23 | @param st [out] The destination of the ChaCha state | |
24 | @param key The secret key | |
25 | @param keylen The length of the secret key (octets) | |
26 | @param rounds Number of rounds (e.g. 20 for ChaCha20) | |
27 | @return CRYPT_OK if successful | |
28 | */ | |
29 | int chacha_setup(chacha_state *st, const unsigned char *key, unsigned long keylen, int rounds) | |
30 | { | |
31 | const char *constants; | |
32 | ||
33 | LTC_ARGCHK(st != NULL); | |
34 | LTC_ARGCHK(key != NULL); | |
35 | LTC_ARGCHK(keylen == 32 || keylen == 16); | |
36 | ||
37 | LOAD32L(st->input[4], key + 0); | |
38 | LOAD32L(st->input[5], key + 4); | |
39 | LOAD32L(st->input[6], key + 8); | |
40 | LOAD32L(st->input[7], key + 12); | |
41 | if (keylen == 32) { /* 256bit */ | |
42 | key += 16; | |
43 | constants = sigma; | |
44 | } else { /* 128bit */ | |
45 | constants = tau; | |
46 | } | |
47 | LOAD32L(st->input[8], key + 0); | |
48 | LOAD32L(st->input[9], key + 4); | |
49 | LOAD32L(st->input[10], key + 8); | |
50 | LOAD32L(st->input[11], key + 12); | |
51 | LOAD32L(st->input[0], constants + 0); | |
52 | LOAD32L(st->input[1], constants + 4); | |
53 | LOAD32L(st->input[2], constants + 8); | |
54 | LOAD32L(st->input[3], constants + 12); | |
55 | st->rounds = rounds; /* e.g. 20 for chacha20 */ | |
56 | return CRYPT_OK; | |
57 | }; | |
58 | ||
59 | #endif |
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 | ||
9 | #include "tomcrypt.h" | |
10 | ||
11 | #ifdef LTC_RC4 | |
12 | ||
13 | /** | |
14 | Initialize an RC4 context (only the key) | |
15 | @param st [out] The destination of the RC4 state | |
16 | @param key The secret key | |
17 | @param keylen The length of the secret key (8 - 256 bytes) | |
18 | @return CRYPT_OK if successful | |
19 | */ | |
20 | int rc4_setup(rc4_state *st, const unsigned char *key, unsigned long keylen) | |
21 | { | |
22 | unsigned char tmp, *s; | |
23 | int x, y; | |
24 | unsigned long j; | |
25 | ||
26 | LTC_ARGCHK(st != NULL); | |
27 | LTC_ARGCHK(key != NULL); | |
28 | LTC_ARGCHK(keylen >= 5); /* 40-2048 bits */ | |
29 | ||
30 | s = st->buf; | |
31 | for (x = 0; x < 256; x++) { | |
32 | s[x] = x; | |
33 | } | |
34 | ||
35 | for (j = x = y = 0; x < 256; x++) { | |
36 | y = (y + s[x] + key[j++]) & 255; | |
37 | if (j == keylen) { | |
38 | j = 0; | |
39 | } | |
40 | tmp = s[x]; s[x] = s[y]; s[y] = tmp; | |
41 | } | |
42 | st->x = 0; | |
43 | st->y = 0; | |
44 | ||
45 | return CRYPT_OK; | |
46 | } | |
47 | ||
48 | /** | |
49 | Encrypt (or decrypt) bytes of ciphertext (or plaintext) with RC4 | |
50 | @param st The RC4 state | |
51 | @param in The plaintext (or ciphertext) | |
52 | @param inlen The length of the input (octets) | |
53 | @param out [out] The ciphertext (or plaintext), length inlen | |
54 | @return CRYPT_OK if successful | |
55 | */ | |
56 | int rc4_crypt(rc4_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out) | |
57 | { | |
58 | unsigned char x, y, *s, tmp; | |
59 | ||
60 | LTC_ARGCHK(st != NULL); | |
61 | LTC_ARGCHK(in != NULL); | |
62 | LTC_ARGCHK(out != NULL); | |
63 | ||
64 | x = st->x; | |
65 | y = st->y; | |
66 | s = st->buf; | |
67 | while (inlen--) { | |
68 | x = (x + 1) & 255; | |
69 | y = (y + s[x]) & 255; | |
70 | tmp = s[x]; s[x] = s[y]; s[y] = tmp; | |
71 | tmp = (s[x] + s[y]) & 255; | |
72 | *out++ = *in++ ^ s[tmp]; | |
73 | } | |
74 | st->x = x; | |
75 | st->y = y; | |
76 | return CRYPT_OK; | |
77 | } | |
78 | ||
79 | /** | |
80 | Generate a stream of random bytes via RC4 | |
81 | @param st The RC420 state | |
82 | @param out [out] The output buffer | |
83 | @param outlen The output length | |
84 | @return CRYPT_OK on success | |
85 | */ | |
86 | int rc4_keystream(rc4_state *st, unsigned char *out, unsigned long outlen) | |
87 | { | |
88 | if (outlen == 0) return CRYPT_OK; /* nothing to do */ | |
89 | LTC_ARGCHK(out != NULL); | |
90 | XMEMSET(out, 0, outlen); | |
91 | return rc4_crypt(st, out, outlen, out); | |
92 | } | |
93 | ||
94 | /** | |
95 | Terminate and clear RC4 state | |
96 | @param st The RC4 state | |
97 | @return CRYPT_OK on success | |
98 | */ | |
99 | int rc4_done(rc4_state *st) | |
100 | { | |
101 | LTC_ARGCHK(st != NULL); | |
102 | XMEMSET(st, 0, sizeof(rc4_state)); | |
103 | return CRYPT_OK; | |
104 | } | |
105 | ||
106 | #endif |
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 | * Tom St Denis, tomstdenis@gmail.com, http://libtom.org | |
9 | */ | |
10 | #include "tomcrypt.h" | |
11 | ||
12 | /** | |
13 | @file sober128.c | |
14 | Implementation of SOBER-128 by Tom St Denis. | |
15 | Based on s128fast.c reference code supplied by Greg Rose of QUALCOMM. | |
16 | */ | |
17 | ||
18 | #ifdef LTC_SOBER128 | |
19 | ||
20 | #define __LTC_SOBER128TAB_C__ | |
21 | #include "sober128tab.c" | |
22 | ||
23 | /* don't change these... */ | |
24 | #define N 17 | |
25 | #define FOLD N /* how many iterations of folding to do */ | |
26 | #define INITKONST 0x6996c53a /* value of KONST to use during key loading */ | |
27 | #define KEYP 15 /* where to insert key words */ | |
28 | #define FOLDP 4 /* where to insert non-linear feedback */ | |
29 | ||
30 | #define B(x,i) ((unsigned char)(((x) >> (8*i)) & 0xFF)) | |
31 | ||
32 | static ulong32 BYTE2WORD(unsigned char *b) | |
33 | { | |
34 | ulong32 t; | |
35 | LOAD32L(t, b); | |
36 | return t; | |
37 | } | |
38 | ||
39 | static void XORWORD(ulong32 w, const unsigned char *in, unsigned char *out) | |
40 | { | |
41 | ulong32 t; | |
42 | LOAD32L(t, in); | |
43 | t ^= w; | |
44 | STORE32L(t, out); | |
45 | } | |
46 | ||
47 | /* give correct offset for the current position of the register, | |
48 | * where logically R[0] is at position "zero". | |
49 | */ | |
50 | #define OFF(zero, i) (((zero)+(i)) % N) | |
51 | ||
52 | /* step the LFSR */ | |
53 | /* After stepping, "zero" moves right one place */ | |
54 | #define STEP(R,z) \ | |
55 | R[OFF(z,0)] = R[OFF(z,15)] ^ R[OFF(z,4)] ^ (R[OFF(z,0)] << 8) ^ Multab[(R[OFF(z,0)] >> 24) & 0xFF]; | |
56 | ||
57 | static void cycle(ulong32 *R) | |
58 | { | |
59 | ulong32 t; | |
60 | int i; | |
61 | ||
62 | STEP(R,0); | |
63 | t = R[0]; | |
64 | for (i = 1; i < N; ++i) { | |
65 | R[i-1] = R[i]; | |
66 | } | |
67 | R[N-1] = t; | |
68 | } | |
69 | ||
70 | /* Return a non-linear function of some parts of the register. | |
71 | */ | |
72 | #define NLFUNC(c,z) \ | |
73 | { \ | |
74 | t = c->R[OFF(z,0)] + c->R[OFF(z,16)]; \ | |
75 | t ^= Sbox[(t >> 24) & 0xFF]; \ | |
76 | t = RORc(t, 8); \ | |
77 | t = ((t + c->R[OFF(z,1)]) ^ c->konst) + c->R[OFF(z,6)]; \ | |
78 | t ^= Sbox[(t >> 24) & 0xFF]; \ | |
79 | t = t + c->R[OFF(z,13)]; \ | |
80 | } | |
81 | ||
82 | static ulong32 nltap(sober128_state *c) | |
83 | { | |
84 | ulong32 t; | |
85 | NLFUNC(c, 0); | |
86 | return t; | |
87 | } | |
88 | ||
89 | /* Save the current register state | |
90 | */ | |
91 | static void s128_savestate(sober128_state *c) | |
92 | { | |
93 | int i; | |
94 | for (i = 0; i < N; ++i) { | |
95 | c->initR[i] = c->R[i]; | |
96 | } | |
97 | } | |
98 | ||
99 | /* initialise to previously saved register state | |
100 | */ | |
101 | static void s128_reloadstate(sober128_state *c) | |
102 | { | |
103 | int i; | |
104 | ||
105 | for (i = 0; i < N; ++i) { | |
106 | c->R[i] = c->initR[i]; | |
107 | } | |
108 | } | |
109 | ||
110 | /* Initialise "konst" | |
111 | */ | |
112 | static void s128_genkonst(sober128_state *c) | |
113 | { | |
114 | ulong32 newkonst; | |
115 | ||
116 | do { | |
117 | cycle(c->R); | |
118 | newkonst = nltap(c); | |
119 | } while ((newkonst & 0xFF000000) == 0); | |
120 | c->konst = newkonst; | |
121 | } | |
122 | ||
123 | /* Load key material into the register | |
124 | */ | |
125 | #define ADDKEY(k) \ | |
126 | c->R[KEYP] += (k); | |
127 | ||
128 | #define XORNL(nl) \ | |
129 | c->R[FOLDP] ^= (nl); | |
130 | ||
131 | /* nonlinear diffusion of register for key */ | |
132 | #define DROUND(z) STEP(c->R,z); NLFUNC(c,(z+1)); c->R[OFF((z+1),FOLDP)] ^= t; | |
133 | static void s128_diffuse(sober128_state *c) | |
134 | { | |
135 | ulong32 t; | |
136 | /* relies on FOLD == N == 17! */ | |
137 | DROUND(0); | |
138 | DROUND(1); | |
139 | DROUND(2); | |
140 | DROUND(3); | |
141 | DROUND(4); | |
142 | DROUND(5); | |
143 | DROUND(6); | |
144 | DROUND(7); | |
145 | DROUND(8); | |
146 | DROUND(9); | |
147 | DROUND(10); | |
148 | DROUND(11); | |
149 | DROUND(12); | |
150 | DROUND(13); | |
151 | DROUND(14); | |
152 | DROUND(15); | |
153 | DROUND(16); | |
154 | } | |
155 | ||
156 | /** | |
157 | Initialize an Sober128 context (only the key) | |
158 | @param c [out] The destination of the Sober128 state | |
159 | @param key The secret key | |
160 | @param keylen The length of the secret key (octets) | |
161 | @return CRYPT_OK if successful | |
162 | */ | |
163 | int sober128_setup(sober128_state *c, const unsigned char *key, unsigned long keylen) | |
164 | { | |
165 | ulong32 i, k; | |
166 | ||
167 | LTC_ARGCHK(c != NULL); | |
168 | LTC_ARGCHK(key != NULL); | |
169 | LTC_ARGCHK(keylen > 0); | |
170 | ||
171 | /* keylen must be multiple of 4 bytes */ | |
172 | if ((keylen & 3) != 0) { | |
173 | return CRYPT_INVALID_KEYSIZE; | |
174 | } | |
175 | ||
176 | /* Register initialised to Fibonacci numbers */ | |
177 | c->R[0] = 1; | |
178 | c->R[1] = 1; | |
179 | for (i = 2; i < N; ++i) { | |
180 | c->R[i] = c->R[i-1] + c->R[i-2]; | |
181 | } | |
182 | c->konst = INITKONST; | |
183 | ||
184 | for (i = 0; i < keylen; i += 4) { | |
185 | k = BYTE2WORD((unsigned char *)&key[i]); | |
186 | ADDKEY(k); | |
187 | cycle(c->R); | |
188 | XORNL(nltap(c)); | |
189 | } | |
190 | ||
191 | /* also fold in the length of the key */ | |
192 | ADDKEY(keylen); | |
193 | ||
194 | /* now diffuse */ | |
195 | s128_diffuse(c); | |
196 | s128_genkonst(c); | |
197 | s128_savestate(c); | |
198 | c->nbuf = 0; | |
199 | ||
200 | return CRYPT_OK; | |
201 | } | |
202 | ||
203 | /** | |
204 | Set IV to the Sober128 state | |
205 | @param c The Sober12820 state | |
206 | @param iv The IV data to add | |
207 | @param inlen The length of the IV (must be 12) | |
208 | @return CRYPT_OK on success | |
209 | */ | |
210 | int sober128_setiv(sober128_state *c, const unsigned char *iv, unsigned long ivlen) | |
211 | { | |
212 | ulong32 i, k; | |
213 | ||
214 | LTC_ARGCHK(c != NULL); | |
215 | LTC_ARGCHK(iv != NULL); | |
216 | LTC_ARGCHK(ivlen > 0); | |
217 | ||
218 | /* ok we are adding an IV then... */ | |
219 | s128_reloadstate(c); | |
220 | ||
221 | /* ivlen must be multiple of 4 bytes */ | |
222 | if ((ivlen & 3) != 0) { | |
223 | return CRYPT_INVALID_KEYSIZE; | |
224 | } | |
225 | ||
226 | for (i = 0; i < ivlen; i += 4) { | |
227 | k = BYTE2WORD((unsigned char *)&iv[i]); | |
228 | ADDKEY(k); | |
229 | cycle(c->R); | |
230 | XORNL(nltap(c)); | |
231 | } | |
232 | ||
233 | /* also fold in the length of the key */ | |
234 | ADDKEY(ivlen); | |
235 | ||
236 | /* now diffuse */ | |
237 | s128_diffuse(c); | |
238 | c->nbuf = 0; | |
239 | ||
240 | return CRYPT_OK; | |
241 | } | |
242 | ||
243 | /* XOR pseudo-random bytes into buffer | |
244 | */ | |
245 | #define SROUND(z) STEP(c->R,z); NLFUNC(c,(z+1)); XORWORD(t, in+(z*4), out+(z*4)); | |
246 | ||
247 | /** | |
248 | Encrypt (or decrypt) bytes of ciphertext (or plaintext) with Sober128 | |
249 | @param c The Sober128 state | |
250 | @param in The plaintext (or ciphertext) | |
251 | @param inlen The length of the input (octets) | |
252 | @param out [out] The ciphertext (or plaintext), length inlen | |
253 | @return CRYPT_OK if successful | |
254 | */ | |
255 | int sober128_crypt(sober128_state *c, const unsigned char *in, unsigned long inlen, unsigned char *out) | |
256 | { | |
257 | ulong32 t; | |
258 | ||
259 | if (inlen == 0) return CRYPT_OK; /* nothing to do */ | |
260 | LTC_ARGCHK(out != NULL); | |
261 | LTC_ARGCHK(c != NULL); | |
262 | ||
263 | /* handle any previously buffered bytes */ | |
264 | while (c->nbuf != 0 && inlen != 0) { | |
265 | *out++ = *in++ ^ (c->sbuf & 0xFF); | |
266 | c->sbuf >>= 8; | |
267 | c->nbuf -= 8; | |
268 | --inlen; | |
269 | } | |
270 | ||
271 | #ifndef LTC_SMALL_CODE | |
272 | /* do lots at a time, if there's enough to do */ | |
273 | while (inlen >= N*4) { | |
274 | SROUND(0); | |
275 | SROUND(1); | |
276 | SROUND(2); | |
277 | SROUND(3); | |
278 | SROUND(4); | |
279 | SROUND(5); | |
280 | SROUND(6); | |
281 | SROUND(7); | |
282 | SROUND(8); | |
283 | SROUND(9); | |
284 | SROUND(10); | |
285 | SROUND(11); | |
286 | SROUND(12); | |
287 | SROUND(13); | |
288 | SROUND(14); | |
289 | SROUND(15); | |
290 | SROUND(16); | |
291 | out += 4*N; | |
292 | in += 4*N; | |
293 | inlen -= 4*N; | |
294 | } | |
295 | #endif | |
296 | ||
297 | /* do small or odd size buffers the slow way */ | |
298 | while (4 <= inlen) { | |
299 | cycle(c->R); | |
300 | t = nltap(c); | |
301 | XORWORD(t, in, out); | |
302 | out += 4; | |
303 | in += 4; | |
304 | inlen -= 4; | |
305 | } | |
306 | ||
307 | /* handle any trailing bytes */ | |
308 | if (inlen != 0) { | |
309 | cycle(c->R); | |
310 | c->sbuf = nltap(c); | |
311 | c->nbuf = 32; | |
312 | while (c->nbuf != 0 && inlen != 0) { | |
313 | *out++ = *in++ ^ (c->sbuf & 0xFF); | |
314 | c->sbuf >>= 8; | |
315 | c->nbuf -= 8; | |
316 | --inlen; | |
317 | } | |
318 | } | |
319 | ||
320 | return CRYPT_OK; | |
321 | } | |
322 | ||
323 | int sober128_keystream(sober128_state *c, unsigned char *out, unsigned long outlen) | |
324 | { | |
325 | if (outlen == 0) return CRYPT_OK; /* nothing to do */ | |
326 | LTC_ARGCHK(out != NULL); | |
327 | XMEMSET(out, 0, outlen); | |
328 | return sober128_crypt(c, out, outlen, out); | |
329 | } | |
330 | ||
331 | /** | |
332 | Terminate and clear Sober128 state | |
333 | @param c The Sober128 state | |
334 | @return CRYPT_OK on success | |
335 | */ | |
336 | int sober128_done(sober128_state *c) | |
337 | { | |
338 | LTC_ARGCHK(c != NULL); | |
339 | XMEMSET(c, 0, sizeof(sober128_state)); | |
340 | return CRYPT_OK; | |
341 | } | |
342 | ||
343 | #endif |
0 | /** | |
1 | @file sober128tab.c | |
2 | SOBER-128 Tables | |
3 | */ | |
4 | ||
5 | #ifdef __LTC_SOBER128TAB_C__ | |
6 | ||
7 | /* $ID$ */ | |
8 | /* @(#)TuringMultab.h 1.3 (QUALCOMM) 02/09/03 */ | |
9 | /* Multiplication table for Turing using 0xD02B4367 */ | |
10 | static const ulong32 Multab[256] = { | |
11 | 0x00000000, 0xD02B4367, 0xED5686CE, 0x3D7DC5A9, | |
12 | 0x97AC41D1, 0x478702B6, 0x7AFAC71F, 0xAAD18478, | |
13 | 0x631582EF, 0xB33EC188, 0x8E430421, 0x5E684746, | |
14 | 0xF4B9C33E, 0x24928059, 0x19EF45F0, 0xC9C40697, | |
15 | 0xC62A4993, 0x16010AF4, 0x2B7CCF5D, 0xFB578C3A, | |
16 | 0x51860842, 0x81AD4B25, 0xBCD08E8C, 0x6CFBCDEB, | |
17 | 0xA53FCB7C, 0x7514881B, 0x48694DB2, 0x98420ED5, | |
18 | 0x32938AAD, 0xE2B8C9CA, 0xDFC50C63, 0x0FEE4F04, | |
19 | 0xC154926B, 0x117FD10C, 0x2C0214A5, 0xFC2957C2, | |
20 | 0x56F8D3BA, 0x86D390DD, 0xBBAE5574, 0x6B851613, | |
21 | 0xA2411084, 0x726A53E3, 0x4F17964A, 0x9F3CD52D, | |
22 | 0x35ED5155, 0xE5C61232, 0xD8BBD79B, 0x089094FC, | |
23 | 0x077EDBF8, 0xD755989F, 0xEA285D36, 0x3A031E51, | |
24 | 0x90D29A29, 0x40F9D94E, 0x7D841CE7, 0xADAF5F80, | |
25 | 0x646B5917, 0xB4401A70, 0x893DDFD9, 0x59169CBE, | |
26 | 0xF3C718C6, 0x23EC5BA1, 0x1E919E08, 0xCEBADD6F, | |
27 | 0xCFA869D6, 0x1F832AB1, 0x22FEEF18, 0xF2D5AC7F, | |
28 | 0x58042807, 0x882F6B60, 0xB552AEC9, 0x6579EDAE, | |
29 | 0xACBDEB39, 0x7C96A85E, 0x41EB6DF7, 0x91C02E90, | |
30 | 0x3B11AAE8, 0xEB3AE98F, 0xD6472C26, 0x066C6F41, | |
31 | 0x09822045, 0xD9A96322, 0xE4D4A68B, 0x34FFE5EC, | |
32 | 0x9E2E6194, 0x4E0522F3, 0x7378E75A, 0xA353A43D, | |
33 | 0x6A97A2AA, 0xBABCE1CD, 0x87C12464, 0x57EA6703, | |
34 | 0xFD3BE37B, 0x2D10A01C, 0x106D65B5, 0xC04626D2, | |
35 | 0x0EFCFBBD, 0xDED7B8DA, 0xE3AA7D73, 0x33813E14, | |
36 | 0x9950BA6C, 0x497BF90B, 0x74063CA2, 0xA42D7FC5, | |
37 | 0x6DE97952, 0xBDC23A35, 0x80BFFF9C, 0x5094BCFB, | |
38 | 0xFA453883, 0x2A6E7BE4, 0x1713BE4D, 0xC738FD2A, | |
39 | 0xC8D6B22E, 0x18FDF149, 0x258034E0, 0xF5AB7787, | |
40 | 0x5F7AF3FF, 0x8F51B098, 0xB22C7531, 0x62073656, | |
41 | 0xABC330C1, 0x7BE873A6, 0x4695B60F, 0x96BEF568, | |
42 | 0x3C6F7110, 0xEC443277, 0xD139F7DE, 0x0112B4B9, | |
43 | 0xD31DD2E1, 0x03369186, 0x3E4B542F, 0xEE601748, | |
44 | 0x44B19330, 0x949AD057, 0xA9E715FE, 0x79CC5699, | |
45 | 0xB008500E, 0x60231369, 0x5D5ED6C0, 0x8D7595A7, | |
46 | 0x27A411DF, 0xF78F52B8, 0xCAF29711, 0x1AD9D476, | |
47 | 0x15379B72, 0xC51CD815, 0xF8611DBC, 0x284A5EDB, | |
48 | 0x829BDAA3, 0x52B099C4, 0x6FCD5C6D, 0xBFE61F0A, | |
49 | 0x7622199D, 0xA6095AFA, 0x9B749F53, 0x4B5FDC34, | |
50 | 0xE18E584C, 0x31A51B2B, 0x0CD8DE82, 0xDCF39DE5, | |
51 | 0x1249408A, 0xC26203ED, 0xFF1FC644, 0x2F348523, | |
52 | 0x85E5015B, 0x55CE423C, 0x68B38795, 0xB898C4F2, | |
53 | 0x715CC265, 0xA1778102, 0x9C0A44AB, 0x4C2107CC, | |
54 | 0xE6F083B4, 0x36DBC0D3, 0x0BA6057A, 0xDB8D461D, | |
55 | 0xD4630919, 0x04484A7E, 0x39358FD7, 0xE91ECCB0, | |
56 | 0x43CF48C8, 0x93E40BAF, 0xAE99CE06, 0x7EB28D61, | |
57 | 0xB7768BF6, 0x675DC891, 0x5A200D38, 0x8A0B4E5F, | |
58 | 0x20DACA27, 0xF0F18940, 0xCD8C4CE9, 0x1DA70F8E, | |
59 | 0x1CB5BB37, 0xCC9EF850, 0xF1E33DF9, 0x21C87E9E, | |
60 | 0x8B19FAE6, 0x5B32B981, 0x664F7C28, 0xB6643F4F, | |
61 | 0x7FA039D8, 0xAF8B7ABF, 0x92F6BF16, 0x42DDFC71, | |
62 | 0xE80C7809, 0x38273B6E, 0x055AFEC7, 0xD571BDA0, | |
63 | 0xDA9FF2A4, 0x0AB4B1C3, 0x37C9746A, 0xE7E2370D, | |
64 | 0x4D33B375, 0x9D18F012, 0xA06535BB, 0x704E76DC, | |
65 | 0xB98A704B, 0x69A1332C, 0x54DCF685, 0x84F7B5E2, | |
66 | 0x2E26319A, 0xFE0D72FD, 0xC370B754, 0x135BF433, | |
67 | 0xDDE1295C, 0x0DCA6A3B, 0x30B7AF92, 0xE09CECF5, | |
68 | 0x4A4D688D, 0x9A662BEA, 0xA71BEE43, 0x7730AD24, | |
69 | 0xBEF4ABB3, 0x6EDFE8D4, 0x53A22D7D, 0x83896E1A, | |
70 | 0x2958EA62, 0xF973A905, 0xC40E6CAC, 0x14252FCB, | |
71 | 0x1BCB60CF, 0xCBE023A8, 0xF69DE601, 0x26B6A566, | |
72 | 0x8C67211E, 0x5C4C6279, 0x6131A7D0, 0xB11AE4B7, | |
73 | 0x78DEE220, 0xA8F5A147, 0x958864EE, 0x45A32789, | |
74 | 0xEF72A3F1, 0x3F59E096, 0x0224253F, 0xD20F6658, | |
75 | }; | |
76 | ||
77 | /* $ID$ */ | |
78 | /* Sbox for SOBER-128 */ | |
79 | /* | |
80 | * This is really the combination of two SBoxes; the least significant | |
81 | * 24 bits comes from: | |
82 | * 8->32 Sbox generated by Millan et. al. at Queensland University of | |
83 | * Technology. See: E. Dawson, W. Millan, L. Burnett, G. Carter, | |
84 | * "On the Design of 8*32 S-boxes". Unpublished report, by the | |
85 | * Information Systems Research Centre, | |
86 | * Queensland University of Technology, 1999. | |
87 | * | |
88 | * The most significant 8 bits are the Skipjack "F table", which can be | |
89 | * found at http://csrc.nist.gov/CryptoToolkit/skipjack/skipjack.pdf . | |
90 | * In this optimised table, though, the intent is to XOR the word from | |
91 | * the table selected by the high byte with the input word. Thus, the | |
92 | * high byte is actually the Skipjack F-table entry XORED with its | |
93 | * table index. | |
94 | */ | |
95 | static const ulong32 Sbox[256] = { | |
96 | 0xa3aa1887, 0xd65e435c, 0x0b65c042, 0x800e6ef4, | |
97 | 0xfc57ee20, 0x4d84fed3, 0xf066c502, 0xf354e8ae, | |
98 | 0xbb2ee9d9, 0x281f38d4, 0x1f829b5d, 0x735cdf3c, | |
99 | 0x95864249, 0xbc2e3963, 0xa1f4429f, 0xf6432c35, | |
100 | 0xf7f40325, 0x3cc0dd70, 0x5f973ded, 0x9902dc5e, | |
101 | 0xda175b42, 0x590012bf, 0xdc94d78c, 0x39aab26b, | |
102 | 0x4ac11b9a, 0x8c168146, 0xc3ea8ec5, 0x058ac28f, | |
103 | 0x52ed5c0f, 0x25b4101c, 0x5a2db082, 0x370929e1, | |
104 | 0x2a1843de, 0xfe8299fc, 0x202fbc4b, 0x833915dd, | |
105 | 0x33a803fa, 0xd446b2de, 0x46233342, 0x4fcee7c3, | |
106 | 0x3ad607ef, 0x9e97ebab, 0x507f859b, 0xe81f2e2f, | |
107 | 0xc55b71da, 0xd7e2269a, 0x1339c3d1, 0x7ca56b36, | |
108 | 0xa6c9def2, 0xb5c9fc5f, 0x5927b3a3, 0x89a56ddf, | |
109 | 0xc625b510, 0x560f85a7, 0xace82e71, 0x2ecb8816, | |
110 | 0x44951e2a, 0x97f5f6af, 0xdfcbc2b3, 0xce4ff55d, | |
111 | 0xcb6b6214, 0x2b0b83e3, 0x549ea6f5, 0x9de041af, | |
112 | 0x792f1f17, 0xf73b99ee, 0x39a65ec0, 0x4c7016c6, | |
113 | 0x857709a4, 0xd6326e01, 0xc7b280d9, 0x5cfb1418, | |
114 | 0xa6aff227, 0xfd548203, 0x506b9d96, 0xa117a8c0, | |
115 | 0x9cd5bf6e, 0xdcee7888, 0x61fcfe64, 0xf7a193cd, | |
116 | 0x050d0184, 0xe8ae4930, 0x88014f36, 0xd6a87088, | |
117 | 0x6bad6c2a, 0x1422c678, 0xe9204de7, 0xb7c2e759, | |
118 | 0x0200248e, 0x013b446b, 0xda0d9fc2, 0x0414a895, | |
119 | 0x3a6cc3a1, 0x56fef170, 0x86c19155, 0xcf7b8a66, | |
120 | 0x551b5e69, 0xb4a8623e, 0xa2bdfa35, 0xc4f068cc, | |
121 | 0x573a6acd, 0x6355e936, 0x03602db9, 0x0edf13c1, | |
122 | 0x2d0bb16d, 0x6980b83c, 0xfeb23763, 0x3dd8a911, | |
123 | 0x01b6bc13, 0xf55579d7, 0xf55c2fa8, 0x19f4196e, | |
124 | 0xe7db5476, 0x8d64a866, 0xc06e16ad, 0xb17fc515, | |
125 | 0xc46feb3c, 0x8bc8a306, 0xad6799d9, 0x571a9133, | |
126 | 0x992466dd, 0x92eb5dcd, 0xac118f50, 0x9fafb226, | |
127 | 0xa1b9cef3, 0x3ab36189, 0x347a19b1, 0x62c73084, | |
128 | 0xc27ded5c, 0x6c8bc58f, 0x1cdde421, 0xed1e47fb, | |
129 | 0xcdcc715e, 0xb9c0ff99, 0x4b122f0f, 0xc4d25184, | |
130 | 0xaf7a5e6c, 0x5bbf18bc, 0x8dd7c6e0, 0x5fb7e420, | |
131 | 0x521f523f, 0x4ad9b8a2, 0xe9da1a6b, 0x97888c02, | |
132 | 0x19d1e354, 0x5aba7d79, 0xa2cc7753, 0x8c2d9655, | |
133 | 0x19829da1, 0x531590a7, 0x19c1c149, 0x3d537f1c, | |
134 | 0x50779b69, 0xed71f2b7, 0x463c58fa, 0x52dc4418, | |
135 | 0xc18c8c76, 0xc120d9f0, 0xafa80d4d, 0x3b74c473, | |
136 | 0xd09410e9, 0x290e4211, 0xc3c8082b, 0x8f6b334a, | |
137 | 0x3bf68ed2, 0xa843cc1b, 0x8d3c0ff3, 0x20e564a0, | |
138 | 0xf8f55a4f, 0x2b40f8e7, 0xfea7f15f, 0xcf00fe21, | |
139 | 0x8a6d37d6, 0xd0d506f1, 0xade00973, 0xefbbde36, | |
140 | 0x84670fa8, 0xfa31ab9e, 0xaedab618, 0xc01f52f5, | |
141 | 0x6558eb4f, 0x71b9e343, 0x4b8d77dd, 0x8cb93da6, | |
142 | 0x740fd52d, 0x425412f8, 0xc5a63360, 0x10e53ad0, | |
143 | 0x5a700f1c, 0x8324ed0b, 0xe53dc1ec, 0x1a366795, | |
144 | 0x6d549d15, 0xc5ce46d7, 0xe17abe76, 0x5f48e0a0, | |
145 | 0xd0f07c02, 0x941249b7, 0xe49ed6ba, 0x37a47f78, | |
146 | 0xe1cfffbd, 0xb007ca84, 0xbb65f4da, 0xb59f35da, | |
147 | 0x33d2aa44, 0x417452ac, 0xc0d674a7, 0x2d61a46a, | |
148 | 0xdc63152a, 0x3e12b7aa, 0x6e615927, 0xa14fb118, | |
149 | 0xa151758d, 0xba81687b, 0xe152f0b3, 0x764254ed, | |
150 | 0x34c77271, 0x0a31acab, 0x54f94aec, 0xb9e994cd, | |
151 | 0x574d9e81, 0x5b623730, 0xce8a21e8, 0x37917f0b, | |
152 | 0xe8a9b5d6, 0x9697adf8, 0xf3d30431, 0x5dcac921, | |
153 | 0x76b35d46, 0xaa430a36, 0xc2194022, 0x22bca65e, | |
154 | 0xdaec70ba, 0xdfaea8cc, 0x777bae8b, 0x242924d5, | |
155 | 0x1f098a5a, 0x4b396b81, 0x55de2522, 0x435c1cb8, | |
156 | 0xaeb8fe1d, 0x9db3c697, 0x5b164f83, 0xe0c16376, | |
157 | 0xa319224c, 0xd0203b35, 0x433ac0fe, 0x1466a19a, | |
158 | 0x45f0b24f, 0x51fda998, 0xc0d52d71, 0xfa0896a8, | |
159 | 0xf9e6053f, 0xa4b0d300, 0xd499cbcc, 0xb95e3d40, | |
160 | }; | |
161 | ||
162 | #endif /* __LTC_SOBER128TAB_C__ */ | |
163 | ||
164 | /* $Source$ */ | |
165 | /* $Revision$ */ | |
166 | /* $Date$ */ |