1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */ 2 /* SPDX-License-Identifier: Unlicense */ 3 4 #include "tomcrypt.h" 5 6 /* 7 * Internal Macros 8 */ 9 /* Static assertion */ 10 #define LTC_STATIC_ASSERT(msg, cond) typedef char ltc_static_assert_##msg[(cond) ? 1 : -1]; 11 12 #define LTC_PAD_MASK (0xF000U) 13 14 #if defined(ENDIAN_64BITWORD) 15 #define CONSTPTR(n) CONST64(n) 16 #else 17 #define CONSTPTR(n) n ## uL 18 #endif 19 20 LTC_STATIC_ASSERT(correct_CONSTPTR_size, sizeof(CONSTPTR(1)) == sizeof(void*)) 21 22 /* Poor-man's `uintptr_t` since we can't use stdint.h 23 * c.f. https://github.com/DCIT/perl-CryptX/issues/95#issuecomment-1745280962 */ 24 typedef size_t ltc_uintptr; 25 26 LTC_STATIC_ASSERT(correct_ltc_uintptr_size, sizeof(ltc_uintptr) == sizeof(void*)) 27 28 /* Aligns a `unsigned char` buffer `buf` to `n` bytes and returns that aligned address. 29 * Make sure that the buffer that is passed is huge enough. 30 */ 31 #define LTC_ALIGN_BUF(buf, n) ((void*)((ltc_uintptr)&((unsigned char*)(buf))[n - 1] & (~(CONSTPTR(n) - CONSTPTR(1))))) 32 33 /* `NULL` as defined by the standard is not guaranteed to be of a pointer 34 * type. In order to make sure that in vararg API's a pointer type is used, 35 * define our own version and use that one internally. 36 */ 37 #ifndef LTC_NULL 38 #define LTC_NULL ((void *)0) 39 #endif 40 41 /* 42 * Internal Enums 43 */ 44 45 enum ltc_oid_id { 46 LTC_OID_RSA, 47 LTC_OID_DSA, 48 LTC_OID_EC, 49 LTC_OID_EC_PRIMEF, 50 LTC_OID_X25519, 51 LTC_OID_ED25519, 52 }; 53 54 /* 55 * Internal Types 56 */ 57 58 typedef struct { 59 int size; 60 const char *name, *base, *prime; 61 } ltc_dh_set_type; 62 63 64 typedef int (*fn_kdf_t)(const unsigned char *password, unsigned long password_len, 65 const unsigned char *salt, unsigned long salt_len, 66 int iteration_count, int hash_idx, 67 unsigned char *out, unsigned long *outlen); 68 69 typedef struct { 70 /* KDF */ 71 fn_kdf_t kdf; 72 /* Hash or HMAC */ 73 const char* h; 74 /* cipher */ 75 const char* c; 76 unsigned long keylen; 77 /* not used for pbkdf2 */ 78 unsigned long blocklen; 79 } pbes_properties; 80 81 typedef struct 82 { 83 pbes_properties type; 84 const void *pwd; 85 unsigned long pwdlen; 86 ltc_asn1_list *enc_data; 87 ltc_asn1_list *salt; 88 ltc_asn1_list *iv; 89 unsigned long iterations; 90 /* only used for RC2 */ 91 unsigned long key_bits; 92 } pbes_arg; 93 94 /* 95 * Internal functions 96 */ 97 98 99 /* tomcrypt_cipher.h */ 100 101 #if defined(LTC_AES_NI) && defined(LTC_AMD64_SSE4_1) 102 #define LTC_HAS_AES_NI 103 #endif 104 105 void blowfish_enc(ulong32 *data, unsigned long blocks, const symmetric_key *skey); 106 int blowfish_expand(const unsigned char *key, int keylen, 107 const unsigned char *data, int datalen, 108 symmetric_key *skey); 109 int blowfish_setup_with_data(const unsigned char *key, int keylen, 110 const unsigned char *data, int datalen, 111 symmetric_key *skey); 112 113 /* tomcrypt_hash.h */ 114 115 /* a macro for making hash "process" functions */ 116 #define HASH_PROCESS_(func_name, compress_name, compress_n_name, state_var, block_size) \ 117 int func_name (hash_state * md, const unsigned char *in, unsigned long inlen) \ 118 { \ 119 unsigned long n, blocks; \ 120 int err; \ 121 int (*compress)(hash_state *, const unsigned char *) = compress_name; \ 122 int (*compress_n)(hash_state *, const unsigned char *, int) = compress_n_name;\ 123 LTC_ARGCHK(md != NULL); \ 124 LTC_ARGCHK(in != NULL); \ 125 if (md-> state_var .curlen > sizeof(md-> state_var .buf)) { \ 126 return CRYPT_INVALID_ARG; \ 127 } \ 128 if (((md-> state_var .length + inlen * 8) < md-> state_var .length) \ 129 || ((inlen * 8) < inlen)) { \ 130 return CRYPT_HASH_OVERFLOW; \ 131 } \ 132 while (inlen > 0) { \ 133 if (md-> state_var .curlen == 0 && inlen >= block_size) { \ 134 if (compress_n) { \ 135 blocks = inlen / block_size; \ 136 err = compress_n (md, in, blocks); \ 137 } else { \ 138 blocks = 1; \ 139 err = compress (md, in); \ 140 } \ 141 if (err != CRYPT_OK) \ 142 return err; \ 143 md-> state_var .length += blocks * block_size * 8; \ 144 in += blocks * block_size; \ 145 inlen -= blocks * block_size; \ 146 } else { \ 147 n = MIN(inlen, (block_size - md-> state_var .curlen)); \ 148 XMEMCPY(md-> state_var .buf + md-> state_var.curlen, in, (size_t)n); \ 149 md-> state_var .curlen += n; \ 150 in += n; \ 151 inlen -= n; \ 152 if (md-> state_var .curlen == block_size) { \ 153 if (compress_n) { \ 154 err = compress_n (md, md-> state_var .buf, 1); \ 155 } else { \ 156 err = compress (md, md-> state_var .buf); \ 157 } \ 158 if (err != CRYPT_OK) { \ 159 return err; \ 160 } \ 161 md-> state_var .length += 8*block_size; \ 162 md-> state_var .curlen = 0; \ 163 } \ 164 } \ 165 } \ 166 return CRYPT_OK; \ 167 } 168 169 /* define a hash "process" function based on a 1-block compress function */ 170 #define HASH_PROCESS(func_name, compress_name, state_var, block_size) \ 171 HASH_PROCESS_(func_name, compress_name, NULL, state_var, block_size) 172 173 /* define a hash "process" function based on a n-block compress function */ 174 #define HASH_PROCESS_NBLOCKS(func_name, compress_n_name, state_var, block_size) \ 175 HASH_PROCESS_(func_name, NULL, compress_n_name, state_var, block_size) 176 177 178 /* tomcrypt_mac.h */ 179 180 int ocb3_int_ntz(unsigned long x); 181 void ocb3_int_xor_blocks(unsigned char *out, const unsigned char *block_a, const unsigned char *block_b, unsigned long block_len); 182 183 184 /* tomcrypt_math.h */ 185 186 #if !defined(DESC_DEF_ONLY) 187 188 #define MP_DIGIT_BIT ltc_mp.bits_per_digit 189 190 /* some handy macros */ 191 #define mp_init(a) ltc_mp.init(a) 192 #define mp_init_multi ltc_init_multi 193 #define mp_init_size(a, b) ltc_mp.init_size(a, b) 194 #define mp_init_multi_size ltc_init_multi_size 195 #define mp_clear(a) ltc_mp.deinit(a) 196 #define mp_clear_multi ltc_deinit_multi 197 #define mp_cleanup_multi ltc_cleanup_multi 198 #define mp_init_copy(a, b) ltc_mp.init_copy(a, b) 199 200 #define mp_neg(a, b) ltc_mp.neg(a, b) 201 #define mp_copy(a, b) ltc_mp.copy(a, b) 202 203 #define mp_set(a, b) ltc_mp.set_int(a, b) 204 #define mp_set_int(a, b) ltc_mp.set_int(a, b) 205 #define mp_get_int(a) ltc_mp.get_int(a) 206 #define mp_get_digit(a, n) ltc_mp.get_digit(a, n) 207 #define mp_get_digit_count(a) ltc_mp.get_digit_count(a) 208 #define mp_cmp(a, b) ltc_mp.compare(a, b) 209 #define mp_cmp_d(a, b) ltc_mp.compare_d(a, b) 210 #define mp_count_bits(a) ltc_mp.count_bits(a) 211 #define mp_cnt_lsb(a) ltc_mp.count_lsb_bits(a) 212 #define mp_2expt(a, b) ltc_mp.twoexpt(a, b) 213 214 #define mp_read_radix(a, b, c) ltc_mp.read_radix(a, b, c) 215 #define mp_toradix(a, b, c) ltc_mp.write_radix(a, b, c) 216 #define mp_unsigned_bin_size(a) ltc_mp.unsigned_size(a) 217 #define mp_to_unsigned_bin(a, b) ltc_mp.unsigned_write(a, b) 218 #define mp_read_unsigned_bin(a, b, c) ltc_mp.unsigned_read(a, b, c) 219 220 #define mp_add(a, b, c) ltc_mp.add(a, b, c) 221 #define mp_add_d(a, b, c) ltc_mp.addi(a, b, c) 222 #define mp_sub(a, b, c) ltc_mp.sub(a, b, c) 223 #define mp_sub_d(a, b, c) ltc_mp.subi(a, b, c) 224 #define mp_mul(a, b, c) ltc_mp.mul(a, b, c) 225 #define mp_mul_d(a, b, c) ltc_mp.muli(a, b, c) 226 #define mp_sqr(a, b) ltc_mp.sqr(a, b) 227 #define mp_sqrtmod_prime(a, b, c) ltc_mp.sqrtmod_prime(a, b, c) 228 #define mp_div(a, b, c, d) ltc_mp.mpdiv(a, b, c, d) 229 #define mp_div_2(a, b) ltc_mp.div_2(a, b) 230 #define mp_mod(a, b, c) ltc_mp.mpdiv(a, b, NULL, c) 231 #define mp_mod_d(a, b, c) ltc_mp.modi(a, b, c) 232 #define mp_gcd(a, b, c) ltc_mp.gcd(a, b, c) 233 #define mp_lcm(a, b, c) ltc_mp.lcm(a, b, c) 234 235 #define mp_addmod(a, b, c, d) ltc_mp.addmod(a, b, c, d) 236 #define mp_submod(a, b, c, d) ltc_mp.submod(a, b, c, d) 237 #define mp_mulmod(a, b, c, d) ltc_mp.mulmod(a, b, c, d) 238 #define mp_sqrmod(a, b, c) ltc_mp.sqrmod(a, b, c) 239 #define mp_invmod(a, b, c) ltc_mp.invmod(a, b, c) 240 241 #define mp_montgomery_setup(a, b) ltc_mp.montgomery_setup(a, b) 242 #define mp_montgomery_normalization(a, b) ltc_mp.montgomery_normalization(a, b) 243 #define mp_montgomery_reduce(a, b, c) ltc_mp.montgomery_reduce(a, b, c) 244 #define mp_montgomery_free(a) ltc_mp.montgomery_deinit(a) 245 246 #define mp_exptmod(a,b,c,d) ltc_mp.exptmod(a,b,c,d) 247 #define mp_prime_is_prime(a, b, c) ltc_mp.isprime(a, b, c) 248 249 #define mp_iszero(a) (mp_cmp_d(a, 0) == LTC_MP_EQ ? LTC_MP_YES : LTC_MP_NO) 250 #define mp_isodd(a) (mp_get_digit_count(a) > 0 ? (mp_get_digit(a, 0) & 1 ? LTC_MP_YES : LTC_MP_NO) : LTC_MP_NO) 251 #define mp_exch(a, b) do { void *ABC__tmp = a; a = b; b = ABC__tmp; } while(0) 252 253 #define mp_tohex(a, b) mp_toradix(a, b, 16) 254 255 #define mp_rand(a, b) ltc_mp.rand(a, b) 256 257 #endif 258 259 260 /* tomcrypt_misc.h */ 261 262 typedef enum { 263 /** Use `\r\n` as line separator */ 264 BASE64_PEM_CRLF = 1, 265 /** Create output with 72 chars line length */ 266 BASE64_PEM_SSH = 2, 267 } base64_pem_flags; 268 269 int base64_encode_pem(const unsigned char *in, unsigned long inlen, 270 char *out, unsigned long *outlen, 271 unsigned int flags); 272 273 void copy_or_zeromem(const unsigned char* src, unsigned char* dest, unsigned long len, int coz); 274 275 int pbes_decrypt(const pbes_arg *arg, unsigned char *dec_data, unsigned long *dec_size); 276 277 int pbes1_extract(const ltc_asn1_list *s, pbes_arg *res); 278 int pbes2_extract(const ltc_asn1_list *s, pbes_arg *res); 279 280 281 /* tomcrypt_pk.h */ 282 283 int rand_bn_bits(void *N, int bits, prng_state *prng, int wprng); 284 int rand_bn_upto(void *N, void *limit, prng_state *prng, int wprng); 285 286 int pk_get_oid(enum ltc_oid_id id, const char **st); 287 int pk_oid_str_to_num(const char *OID, unsigned long *oid, unsigned long *oidlen); 288 int pk_oid_num_to_str(const unsigned long *oid, unsigned long oidlen, char *OID, unsigned long *outlen); 289 290 /* ---- DH Routines ---- */ 291 #ifdef LTC_MRSA 292 int rsa_init(rsa_key *key); 293 void rsa_shrink_key(rsa_key *key); 294 int rsa_make_key_bn_e(prng_state *prng, int wprng, int size, void *e, 295 rsa_key *key); /* used by op-tee */ 296 int rsa_import_pkcs1(const unsigned char *in, unsigned long inlen, rsa_key *key); 297 #endif /* LTC_MRSA */ 298 299 /* ---- DH Routines ---- */ 300 #ifdef LTC_MDH 301 extern const ltc_dh_set_type ltc_dh_sets[]; 302 303 int dh_check_pubkey(const dh_key *key); 304 #endif /* LTC_MDH */ 305 306 /* ---- ECC Routines ---- */ 307 #ifdef LTC_MECC 308 int ecc_set_curve_from_mpis(void *a, void *b, void *prime, void *order, void *gx, void *gy, unsigned long cofactor, ecc_key *key); 309 int ecc_copy_curve(const ecc_key *srckey, ecc_key *key); 310 int ecc_set_curve_by_size(int size, ecc_key *key); 311 int ecc_import_subject_public_key_info(const unsigned char *in, unsigned long inlen, ecc_key *key); 312 313 #ifdef LTC_SSH 314 int ecc_ssh_ecdsa_encode_name(char *buffer, unsigned long *buflen, const ecc_key *key); 315 #endif 316 317 /* low level functions */ 318 ecc_point *ltc_ecc_new_point(void); 319 void ltc_ecc_del_point(ecc_point *p); 320 int ltc_ecc_set_point_xyz(ltc_mp_digit x, ltc_mp_digit y, ltc_mp_digit z, ecc_point *p); 321 int ltc_ecc_copy_point(const ecc_point *src, ecc_point *dst); 322 int ltc_ecc_is_point(const ltc_ecc_dp *dp, void *x, void *y); 323 int ltc_ecc_is_point_at_infinity(const ecc_point *P, void *modulus, int *retval); 324 int ltc_ecc_import_point(const unsigned char *in, unsigned long inlen, void *prime, void *a, void *b, void *x, void *y); 325 int ltc_ecc_export_point(unsigned char *out, unsigned long *outlen, void *x, void *y, unsigned long size, int compressed); 326 int ltc_ecc_verify_key(const ecc_key *key); 327 328 /* point ops (mp == montgomery digit) */ 329 #if !defined(LTC_MECC_ACCEL) || defined(LTM_DESC) || defined(GMP_DESC) 330 /* R = 2P */ 331 int ltc_ecc_projective_dbl_point(const ecc_point *P, ecc_point *R, void *ma, void *modulus, void *mp); 332 333 /* R = P + Q */ 334 int ltc_ecc_projective_add_point(const ecc_point *P, const ecc_point *Q, ecc_point *R, void *ma, void *modulus, void *mp); 335 #endif 336 337 #if defined(LTC_MECC_FP) 338 /* optimized point multiplication using fixed point cache (HAC algorithm 14.117) */ 339 int ltc_ecc_fp_mulmod(void *k, ecc_point *G, ecc_point *R, void *a, void *modulus, int map); 340 341 /* functions for saving/loading/freeing/adding to fixed point cache */ 342 int ltc_ecc_fp_save_state(unsigned char **out, unsigned long *outlen); 343 int ltc_ecc_fp_restore_state(unsigned char *in, unsigned long inlen); 344 void ltc_ecc_fp_free(void); 345 int ltc_ecc_fp_add_point(ecc_point *g, void *modulus, int lock); 346 347 /* lock/unlock all points currently in fixed point cache */ 348 void ltc_ecc_fp_tablelock(int lock); 349 #endif 350 351 /* R = kG */ 352 int ltc_ecc_mulmod(void *k, const ecc_point *G, ecc_point *R, void *a, void *modulus, int map); 353 354 #ifdef LTC_ECC_SHAMIR 355 /* kA*A + kB*B = C */ 356 int ltc_ecc_mul2add(const ecc_point *A, void *kA, 357 const ecc_point *B, void *kB, 358 ecc_point *C, 359 void *ma, 360 void *modulus); 361 362 #ifdef LTC_MECC_FP 363 /* Shamir's trick with optimized point multiplication using fixed point cache */ 364 int ltc_ecc_fp_mul2add(const ecc_point *A, void *kA, 365 const ecc_point *B, void *kB, 366 ecc_point *C, 367 void *ma, 368 void *modulus); 369 #endif 370 371 #endif 372 373 374 /* map P to affine from projective */ 375 int ltc_ecc_map(ecc_point *P, void *modulus, void *mp); 376 #endif /* LTC_MECC */ 377 378 #ifdef LTC_MDSA 379 int dsa_int_validate_xy(const dsa_key *key, int *stat); 380 int dsa_int_validate_pqg(const dsa_key *key, int *stat); 381 int dsa_int_validate_primes(const dsa_key *key, int *stat); 382 #endif /* LTC_MDSA */ 383 384 385 #ifdef LTC_CURVE25519 386 387 int tweetnacl_crypto_sign( 388 unsigned char *sm,unsigned long long *smlen, 389 const unsigned char *m,unsigned long long mlen, 390 const unsigned char *sk,const unsigned char *pk, 391 const unsigned char *ctx,unsigned long long cs); 392 int tweetnacl_crypto_sign_open( 393 int *stat, 394 unsigned char *m,unsigned long long *mlen, 395 const unsigned char *sm,unsigned long long smlen, 396 const unsigned char *ctx, unsigned long long cs, 397 const unsigned char *pk); 398 int tweetnacl_crypto_sign_keypair(prng_state *prng, int wprng, unsigned char *pk,unsigned char *sk); 399 int tweetnacl_crypto_sk_to_pk(unsigned char *pk, const unsigned char *sk); 400 int tweetnacl_crypto_scalarmult(unsigned char *q, const unsigned char *n, const unsigned char *p); 401 int tweetnacl_crypto_scalarmult_base(unsigned char *q,const unsigned char *n); 402 int tweetnacl_crypto_ph(unsigned char *out, const unsigned char *msg, unsigned long long msglen); 403 404 typedef int (*sk_to_pk)(unsigned char *pk ,const unsigned char *sk); 405 int ec25519_import_pkcs8(const unsigned char *in, unsigned long inlen, 406 const void *pwd, unsigned long pwdlen, 407 enum ltc_oid_id id, sk_to_pk fp, 408 curve25519_key *key); 409 int ec25519_export( unsigned char *out, unsigned long *outlen, 410 int which, 411 const curve25519_key *key); 412 int ec25519_crypto_ctx( unsigned char *out, unsigned long *outlen, 413 unsigned char flag, 414 const unsigned char *ctx, unsigned long ctxlen); 415 #endif /* LTC_CURVE25519 */ 416 417 #ifdef LTC_DER 418 419 #define LTC_ASN1_IS_TYPE(e, t) (((e) != NULL) && ((e)->type == (t))) 420 421 /* DER handling */ 422 int der_decode_custom_type_ex(const unsigned char *in, unsigned long inlen, 423 ltc_asn1_list *root, 424 ltc_asn1_list *list, unsigned long outlen, unsigned int flags); 425 426 int der_encode_asn1_identifier(const ltc_asn1_list *id, unsigned char *out, unsigned long *outlen); 427 int der_decode_asn1_identifier(const unsigned char *in, unsigned long *inlen, ltc_asn1_list *id); 428 int der_length_asn1_identifier(const ltc_asn1_list *id, unsigned long *idlen); 429 430 int der_encode_asn1_length(unsigned long len, unsigned char* out, unsigned long* outlen); 431 int der_decode_asn1_length(const unsigned char *in, unsigned long *inlen, unsigned long *outlen); 432 int der_length_asn1_length(unsigned long len, unsigned long *outlen); 433 434 int der_length_sequence_ex(const ltc_asn1_list *list, unsigned long inlen, 435 unsigned long *outlen, unsigned long *payloadlen); 436 437 extern const ltc_asn1_type der_asn1_tag_to_type_map[]; 438 extern const unsigned long der_asn1_tag_to_type_map_sz; 439 440 extern const int der_asn1_type_to_identifier_map[]; 441 extern const unsigned long der_asn1_type_to_identifier_map_sz; 442 443 int der_decode_sequence_multi_ex(const unsigned char *in, unsigned long inlen, unsigned int flags, ...) 444 LTC_NULL_TERMINATED; 445 446 int der_teletex_char_encode(int c); 447 int der_teletex_value_decode(int v); 448 449 int der_utf8_valid_char(const wchar_t c); 450 451 typedef int (*public_key_decode_cb)(const unsigned char *in, unsigned long inlen, void *ctx); 452 453 int x509_decode_public_key_from_certificate(const unsigned char *in, unsigned long inlen, 454 enum ltc_oid_id algorithm, ltc_asn1_type param_type, 455 ltc_asn1_list* parameters, unsigned long *parameters_len, 456 public_key_decode_cb callback, void *ctx); 457 458 /* SUBJECT PUBLIC KEY INFO */ 459 int x509_encode_subject_public_key_info(unsigned char *out, unsigned long *outlen, 460 unsigned int algorithm, const void* public_key, unsigned long public_key_len, 461 ltc_asn1_type parameters_type, ltc_asn1_list* parameters, unsigned long parameters_len); 462 463 int x509_decode_subject_public_key_info(const unsigned char *in, unsigned long inlen, 464 unsigned int algorithm, void* public_key, unsigned long* public_key_len, 465 ltc_asn1_type parameters_type, ltc_asn1_list* parameters, unsigned long *parameters_len); 466 467 int pk_oid_cmp_with_ulong(const char *o1, const unsigned long *o2, unsigned long o2size); 468 int pk_oid_cmp_with_asn1(const char *o1, const ltc_asn1_list *o2); 469 470 #endif /* LTC_DER */ 471 472 /* tomcrypt_pkcs.h */ 473 474 #ifdef LTC_PKCS_8 475 476 int pkcs8_decode_flexi(const unsigned char *in, unsigned long inlen, 477 const void *pwd, unsigned long pwdlen, 478 ltc_asn1_list **decoded_list); 479 480 #endif /* LTC_PKCS_8 */ 481 482 483 #ifdef LTC_PKCS_12 484 485 int pkcs12_utf8_to_utf16(const unsigned char *in, unsigned long inlen, 486 unsigned char *out, unsigned long *outlen); 487 488 int pkcs12_kdf( int hash_id, 489 const unsigned char *pw, unsigned long pwlen, 490 const unsigned char *salt, unsigned long saltlen, 491 unsigned int iterations, unsigned char purpose, 492 unsigned char *out, unsigned long outlen); 493 494 #endif /* LTC_PKCS_12 */ 495 496 /* tomcrypt_prng.h */ 497 498 #define LTC_PRNG_EXPORT(which) \ 499 int which ## _export(unsigned char *out, unsigned long *outlen, prng_state *prng) \ 500 { \ 501 unsigned long len = which ## _desc.export_size; \ 502 \ 503 LTC_ARGCHK(prng != NULL); \ 504 LTC_ARGCHK(out != NULL); \ 505 LTC_ARGCHK(outlen != NULL); \ 506 \ 507 if (*outlen < len) { \ 508 *outlen = len; \ 509 return CRYPT_BUFFER_OVERFLOW; \ 510 } \ 511 \ 512 if (which ## _read(out, len, prng) != len) { \ 513 return CRYPT_ERROR_READPRNG; \ 514 } \ 515 \ 516 *outlen = len; \ 517 return CRYPT_OK; \ 518 } 519 520 /* extract a byte portably */ 521 #ifdef _MSC_VER 522 #define LTC_BYTE(x, n) ((unsigned char)((x) >> (8 * (n)))) 523 #else 524 #define LTC_BYTE(x, n) (((x) >> (8 * (n))) & 255) 525 #endif 526