diff --git a/include/cx_stubs.h b/include/cx_stubs.h index 4cc5de86f..2b8ba165d 100644 --- a/include/cx_stubs.h +++ b/include/cx_stubs.h @@ -28,107 +28,108 @@ #define _NR_cx_blake2b_get_output_size 0x18 #define _NR_cx_blake2b_init2_no_throw 0x19 #define _NR_cx_blake2b_init_no_throw 0x1a -#define _NR_cx_blake2b_update 0x1b -#define _NR_cx_cipher_enc_dec 0x1c -#define _NR_cx_cipher_finish 0x1d -#define _NR_cx_cipher_init 0x1e -#define _NR_cx_cipher_setiv 0x1f -#define _NR_cx_cipher_setkey 0x20 -#define _NR_cx_cipher_setup 0x21 -#define _NR_cx_cipher_set_padding 0x22 -#define _NR_cx_cipher_update 0x23 -#define _NR_cx_cmac 0x24 -#define _NR_cx_constant_time_eq 0x25 -#define _NR_cx_crc16 0x26 -#define _NR_cx_crc16_update 0x27 -#define _NR_cx_crc32 0x28 -#define _NR_cx_decode_coord 0x29 -#define _NR_cx_ecdh_no_throw 0x2f -#define _NR_cx_ecdsa_sign_no_throw 0x30 -#define _NR_cx_ecdsa_verify_no_throw 0x31 -#define _NR_cx_ecfp_add_point_no_throw 0x32 -#define _NR_cx_ecfp_decode_sig_der 0x33 -#define _NR_cx_ecfp_encode_sig_der 0x34 -#define _NR_cx_ecfp_generate_pair2_no_throw 0x35 -#define _NR_cx_ecfp_generate_pair_no_throw 0x36 -#define _NR_cx_ecfp_init_private_key_no_throw 0x37 -#define _NR_cx_ecfp_init_public_key_no_throw 0x38 -#define _NR_cx_ecfp_scalar_mult_no_throw 0x39 -#define _NR_cx_ecschnorr_sign_no_throw 0x3a -#define _NR_cx_ecschnorr_verify 0x3b -#define _NR_cx_eddsa_get_public_key_internal 0x3c -#define _NR_cx_eddsa_get_public_key_no_throw 0x3d -#define _NR_cx_eddsa_sign_no_throw 0x3e -#define _NR_cx_eddsa_verify_no_throw 0x3f -#define _NR_cx_edwards_compress_point_no_throw 0x40 -#define _NR_cx_edwards_decompress_point_no_throw 0x41 -#define _NR_cx_encode_coord 0x42 -#define _NR_cx_hash_final 0x43 -#define _NR_cx_hash_get_info 0x44 -#define _NR_cx_hash_get_size 0x45 -#define _NR_cx_hash_init 0x46 -#define _NR_cx_hash_init_ex 0x47 -#define _NR_cx_hash_no_throw 0x48 -#define _NR_cx_hash_ripemd160 0x49 -#define _NR_cx_hash_sha256 0x4a -#define _NR_cx_hash_sha512 0x4b -#define _NR_cx_hash_update 0x4c -#define _NR_cx_hkdf_expand 0x4d -#define _NR_cx_hkdf_extract 0x4e -#define _NR_cx_hmac_final 0x4f -#define _NR_cx_hmac_init 0x50 -#define _NR_cx_hmac_no_throw 0x51 -#define _NR_cx_hmac_ripemd160_init_no_throw 0x52 -#define _NR_cx_hmac_sha224_init 0x53 -#define _NR_cx_hmac_sha256 0x54 -#define _NR_cx_hmac_sha256_init_no_throw 0x55 -#define _NR_cx_hmac_sha384_init 0x56 -#define _NR_cx_hmac_sha512 0x57 -#define _NR_cx_hmac_sha512_init_no_throw 0x58 -#define _NR_cx_hmac_update 0x59 -#define _NR_cx_keccak_init_no_throw 0x5a -#define _NR_cx_math_addm_no_throw 0x5b -#define _NR_cx_math_add_no_throw 0x5c -#define _NR_cx_math_cmp_no_throw 0x5d -#define _NR_cx_math_invintm_no_throw 0x5e -#define _NR_cx_math_invprimem_no_throw 0x5f -#define _NR_cx_math_is_prime_no_throw 0x60 -#define _NR_cx_math_modm_no_throw 0x61 -#define _NR_cx_math_multm_no_throw 0x62 -#define _NR_cx_math_mult_no_throw 0x63 -#define _NR_cx_math_next_prime_no_throw 0x64 -#define _NR_cx_math_powm_no_throw 0x65 -#define _NR_cx_math_subm_no_throw 0x66 -#define _NR_cx_math_sub_no_throw 0x67 -#define _NR_cx_memxor 0x68 -#define _NR_cx_pbkdf2_hmac 0x69 -#define _NR_cx_pbkdf2_no_throw 0x6a -#define _NR_cx_ripemd160_final 0x6b -#define _NR_cx_ripemd160_init_no_throw 0x6c -#define _NR_cx_ripemd160_update 0x6d -#define _NR_cx_rng_no_throw 0x6e -#define _NR_cx_rng_rfc6979 0x6f -#define _NR_cx_rng_rfc6979_init 0x70 -#define _NR_cx_rng_rfc6979_next 0x71 -#define _NR_cx_rng_u32_range_func 0x72 -#define _NR_cx_sha224_init_no_throw 0x73 -#define _NR_cx_sha256_final 0x74 -#define _NR_cx_sha256_init_no_throw 0x75 -#define _NR_cx_sha256_update 0x76 -#define _NR_cx_sha384_init_no_throw 0x77 -#define _NR_cx_sha3_final 0x78 -#define _NR_cx_sha3_get_output_size 0x79 -#define _NR_cx_sha3_init_no_throw 0x7a -#define _NR_cx_sha3_update 0x7b -#define _NR_cx_sha3_xof_init_no_throw 0x7c -#define _NR_cx_sha512_final 0x7d -#define _NR_cx_sha512_init_no_throw 0x7e -#define _NR_cx_sha512_update 0x7f -#define _NR_cx_shake128_init_no_throw 0x80 -#define _NR_cx_shake256_init_no_throw 0x81 -#define _NR_cx_swap_buffer32 0x82 -#define _NR_cx_swap_buffer64 0x83 -#define _NR_cx_swap_uint32 0x84 -#define _NR_cx_swap_uint64 0x85 -#define _NR_cx_x25519 0x86 -#define _NR_cx_x448 0x87 +#define _NR_cx_blake2b_init_key 0x1b +#define _NR_cx_blake2b_update 0x1c +#define _NR_cx_cipher_enc_dec 0x1d +#define _NR_cx_cipher_finish 0x1e +#define _NR_cx_cipher_init 0x1f +#define _NR_cx_cipher_setiv 0x20 +#define _NR_cx_cipher_setkey 0x21 +#define _NR_cx_cipher_setup 0x22 +#define _NR_cx_cipher_set_padding 0x23 +#define _NR_cx_cipher_update 0x24 +#define _NR_cx_cmac 0x25 +#define _NR_cx_constant_time_eq 0x26 +#define _NR_cx_crc16 0x27 +#define _NR_cx_crc16_update 0x28 +#define _NR_cx_crc32 0x29 +#define _NR_cx_decode_coord 0x2a +#define _NR_cx_ecdh_no_throw 0x2b +#define _NR_cx_ecdsa_sign_no_throw 0x2c +#define _NR_cx_ecdsa_verify_no_throw 0x2d +#define _NR_cx_ecfp_add_point_no_throw 0x2e +#define _NR_cx_ecfp_decode_sig_der 0x2f +#define _NR_cx_ecfp_encode_sig_der 0x30 +#define _NR_cx_ecfp_generate_pair2_no_throw 0x31 +#define _NR_cx_ecfp_generate_pair_no_throw 0x32 +#define _NR_cx_ecfp_init_private_key_no_throw 0x33 +#define _NR_cx_ecfp_init_public_key_no_throw 0x34 +#define _NR_cx_ecfp_scalar_mult_no_throw 0x35 +#define _NR_cx_ecschnorr_sign_no_throw 0x36 +#define _NR_cx_ecschnorr_verify 0x37 +#define _NR_cx_eddsa_get_public_key_internal 0x38 +#define _NR_cx_eddsa_get_public_key_no_throw 0x39 +#define _NR_cx_eddsa_sign_no_throw 0x3a +#define _NR_cx_eddsa_verify_no_throw 0x3b +#define _NR_cx_edwards_compress_point_no_throw 0x3c +#define _NR_cx_edwards_decompress_point_no_throw 0x3d +#define _NR_cx_encode_coord 0x3e +#define _NR_cx_hash_final 0x3f +#define _NR_cx_hash_get_info 0x40 +#define _NR_cx_hash_get_size 0x41 +#define _NR_cx_hash_init 0x42 +#define _NR_cx_hash_init_ex 0x43 +#define _NR_cx_hash_no_throw 0x44 +#define _NR_cx_hash_ripemd160 0x45 +#define _NR_cx_hash_sha256 0x46 +#define _NR_cx_hash_sha512 0x47 +#define _NR_cx_hash_update 0x48 +#define _NR_cx_hkdf_expand 0x49 +#define _NR_cx_hkdf_extract 0x4a +#define _NR_cx_hmac_final 0x4b +#define _NR_cx_hmac_init 0x4c +#define _NR_cx_hmac_no_throw 0x4d +#define _NR_cx_hmac_ripemd160_init_no_throw 0x4e +#define _NR_cx_hmac_sha224_init 0x4f +#define _NR_cx_hmac_sha256 0x50 +#define _NR_cx_hmac_sha256_init_no_throw 0x51 +#define _NR_cx_hmac_sha384_init 0x52 +#define _NR_cx_hmac_sha512 0x53 +#define _NR_cx_hmac_sha512_init_no_throw 0x54 +#define _NR_cx_hmac_update 0x55 +#define _NR_cx_keccak_init_no_throw 0x56 +#define _NR_cx_math_addm_no_throw 0x57 +#define _NR_cx_math_add_no_throw 0x58 +#define _NR_cx_math_cmp_no_throw 0x59 +#define _NR_cx_math_invintm_no_throw 0x5a +#define _NR_cx_math_invprimem_no_throw 0x5b +#define _NR_cx_math_is_prime_no_throw 0x5c +#define _NR_cx_math_modm_no_throw 0x5d +#define _NR_cx_math_multm_no_throw 0x5e +#define _NR_cx_math_mult_no_throw 0x5f +#define _NR_cx_math_next_prime_no_throw 0x60 +#define _NR_cx_math_powm_no_throw 0x61 +#define _NR_cx_math_subm_no_throw 0x62 +#define _NR_cx_math_sub_no_throw 0x63 +#define _NR_cx_memxor 0x64 +#define _NR_cx_pbkdf2_hmac 0x65 +#define _NR_cx_pbkdf2_no_throw 0x66 +#define _NR_cx_ripemd160_final 0x67 +#define _NR_cx_ripemd160_init_no_throw 0x68 +#define _NR_cx_ripemd160_update 0x69 +#define _NR_cx_rng_no_throw 0x6a +#define _NR_cx_rng_rfc6979 0x6b +#define _NR_cx_rng_rfc6979_init 0x6c +#define _NR_cx_rng_rfc6979_next 0x6d +#define _NR_cx_rng_u32_range_func 0x6e +#define _NR_cx_sha224_init_no_throw 0x6f +#define _NR_cx_sha256_final 0x70 +#define _NR_cx_sha256_init_no_throw 0x71 +#define _NR_cx_sha256_update 0x72 +#define _NR_cx_sha384_init_no_throw 0x73 +#define _NR_cx_sha3_final 0x74 +#define _NR_cx_sha3_get_output_size 0x75 +#define _NR_cx_sha3_init_no_throw 0x76 +#define _NR_cx_sha3_update 0x77 +#define _NR_cx_sha3_xof_init_no_throw 0x78 +#define _NR_cx_sha512_final 0x79 +#define _NR_cx_sha512_init_no_throw 0x7a +#define _NR_cx_sha512_update 0x7b +#define _NR_cx_shake128_init_no_throw 0x7c +#define _NR_cx_shake256_init_no_throw 0x7d +#define _NR_cx_swap_buffer32 0x7e +#define _NR_cx_swap_buffer64 0x7f +#define _NR_cx_swap_uint32 0x80 +#define _NR_cx_swap_uint64 0x81 +#define _NR_cx_x25519 0x82 +#define _NR_cx_x448 0x83 diff --git a/lib_cxng/cx.export b/lib_cxng/cx.export index dc66199ad..1dec1fa33 100644 --- a/lib_cxng/cx.export +++ b/lib_cxng/cx.export @@ -31,6 +31,7 @@ cx_blake2b_final cx_blake2b_get_output_size cx_blake2b_init2_no_throw cx_blake2b_init_no_throw +cx_blake2b_init_key cx_blake2b_update cx_cipher_enc_dec cx_cipher_finish diff --git a/lib_cxng/include/lcx_blake2.h b/lib_cxng/include/lcx_blake2.h index 75ad091f1..1792d8746 100644 --- a/lib_cxng/include/lcx_blake2.h +++ b/lib_cxng/include/lcx_blake2.h @@ -98,77 +98,79 @@ DEPRECATED static inline int cx_blake2b_init(cx_blake2b_t *hash, unsigned int ou } /** - * @brief Computes a standalone one shot BLAKE2B_256 digest. + * @brief Computes a standalone one shot BLAKE2B digest. * * @param[in] iovec Input data in the form of an array of cx_iovec_t. * * @param[in] iovec_len Length of the iovec array. * + * @param[in] key (Optional) Pointer to the key if not NULL. + * + * @param[in] key_len Key length at most 64 bytes + * + * @param[in] salt (Optional) Pointer to the salt if not NULL. + * + * @param[in] salt_len Salt length: 16 bytes if salt is not NULL, otherwise 0. + * + * @param[in] perso (Optional) Pointer to the personalization string if not NULL. + * + * @param[in] perso_len Personalization length: 16 bytes if perso is not NULL, otherwise 0. + * * @param[out] digest Buffer where to store the digest. * * @return Error code: * - CX_OK on success */ -cx_err_t cx_blake2b_256_hash_iovec(const cx_iovec_t *iovec, - size_t iovec_len, - uint8_t digest[static CX_BLAKE2B_256_SIZE]); +cx_err_t cx_blake2b_hash_iovec(const cx_iovec_t *iovec, + size_t iovec_len, + uint8_t *key, + size_t key_len, + uint8_t *salt, + size_t salt_len, + uint8_t *perso, + size_t perso_len, + uint8_t *digest, + size_t digest_len); /** - * @brief Computes a standalone one shot BLAKE2B_256 digest. + * @brief Computes a standalone one shot BLAKE2B digest. * - * @param[in] in Input data. + * @param[in] in Input data. * - * @param[in] len Length of the input data. + * @param[in] len Length of the input data. * - * @param[out] digest Buffer where to store the digest. + * @param[in] key (Optional) Pointer to the key is not NULL. * - * @return Error code: - * - CX_OK on success - */ -static inline cx_err_t cx_blake2b_256_hash(const uint8_t *in, - size_t in_len, - uint8_t digest[static CX_BLAKE2B_256_SIZE]) -{ - const cx_iovec_t iovec = {.iov_base = in, .iov_len = in_len}; - - return cx_blake2b_256_hash_iovec(&iovec, 1, digest); -} - -/** - * @brief Computes a standalone one shot BLAKE2B_512 digest. + * @param[in] key_len Key length at most 64 bytes if key is not NULL otherwise 0. * - * @param[in] iovec Input data in the form of an array of cx_iovec_t. + * @param[in] salt (Optional) Pointer to the salt is not NULL. * - * @param[in] iovec_len Length of the iovec array. + * @param[in] salt_len Salt length: 16 bytes if salt is not NULL, otherwise 0. + * + * @param[in] perso (Optional) Pointer to the personalization string is not NULL. + * + * @param[in] perso_len Personalization length: 16 bytes if perso is not NULL, otherwise 0. * * @param[out] digest Buffer where to store the digest. * * @return Error code: * - CX_OK on success */ -cx_err_t cx_blake2b_512_hash_iovec(const cx_iovec_t *iovec, - size_t iovec_len, - uint8_t digest[static CX_BLAKE2B_512_SIZE]); - -/** - * @brief Computes a standalone one shot BLAKE2B_512 digest. - * - * @param[in] in Input data. - * - * @param[in] len Length of the input data. - * - * @param[out] digest Buffer where to store the digest. - * - * @return Error code: - * - CX_OK on success - */ -static inline cx_err_t cx_blake2b_512_hash(const uint8_t *in, - size_t in_len, - uint8_t digest[static CX_BLAKE2B_512_SIZE]) +static inline cx_err_t cx_blake2b_hash(const uint8_t *in, + size_t in_len, + uint8_t *key, + size_t key_len, + uint8_t *salt, + size_t salt_len, + uint8_t *perso, + size_t perso_len, + uint8_t *digest, + size_t digest_len) { const cx_iovec_t iovec = {.iov_base = in, .iov_len = in_len}; - return cx_blake2b_512_hash_iovec(&iovec, 1, digest); + return cx_blake2b_hash_iovec( + &iovec, 1, key, key_len, salt, salt_len, perso, perso_len, digest, digest_len); } /** @@ -199,6 +201,20 @@ WARN_UNUSED_RESULT cx_err_t cx_blake2b_init2_no_throw(cx_blake2b_t *hash, uint8_t *perso, size_t perso_len); +/** + * @brief Initializes Blake2b key for keyed-hashing. + * + * @param[in] hash Pointer to the BLAKE2b context to initialize. + * + * @param[in] key Pointer to the key if not NULL. + * + * @param[in] key_len Key length if the key is not NULL otherwise 0. + * + * @return Error code: + * -CX_OK on success + */ +WARN_UNUSED_RESULT cx_err_t cx_blake2b_init_key(cx_blake2b_t *hash, uint8_t *key, size_t key_len); + /** * @deprecated * See #cx_blake2b_init2_no_throw diff --git a/lib_cxng/src/cx_blake2b.c b/lib_cxng/src/cx_blake2b.c index 426069b6d..7b3671e56 100644 --- a/lib_cxng/src/cx_blake2b.c +++ b/lib_cxng/src/cx_blake2b.c @@ -31,6 +31,9 @@ #endif #endif +/** Salt and Perso are 16-byte long for BLAKE2B */ +#define CX_BLAKE2B_SALT_PERSO_LEN (16) + const cx_hash_info_t cx_blake2b_info = {CX_BLAKE2B, 0, @@ -60,7 +63,7 @@ cx_err_t cx_blake2b_init2_no_throw(cx_blake2b_t *hash, if (perso == NULL && perso_len != 0) { goto err; } - if (salt_len > 16 || perso_len > 16) { + if (salt_len > CX_BLAKE2B_SALT_PERSO_LEN || perso_len > CX_BLAKE2B_SALT_PERSO_LEN) { goto err; } if (size % 8 != 0 || size < 8 || size > 512) { @@ -81,6 +84,14 @@ cx_err_t cx_blake2b_init2_no_throw(cx_blake2b_t *hash, return CX_INVALID_PARAMETER; } +cx_err_t cx_blake2b_init_key(cx_blake2b_t *hash, uint8_t *key, size_t key_len) +{ + if ((NULL == key) && (0 == key_len)) { + return CX_OK; + } + return blake2b_init_key(&hash->ctx, hash->output_size, key, key_len); +} + cx_err_t cx_blake2b_update(cx_blake2b_t *ctx, const uint8_t *data, size_t len) { if (ctx == NULL) { diff --git a/lib_cxng/src/cx_exported_functions.c b/lib_cxng/src/cx_exported_functions.c index ae43ceb8b..a747623fa 100644 --- a/lib_cxng/src/cx_exported_functions.c +++ b/lib_cxng/src/cx_exported_functions.c @@ -51,6 +51,7 @@ unsigned long __attribute((section("._cx_exported_functions"))) cx_exported_func [_NR_cx_blake2b_get_output_size] = (unsigned long) cx_blake2b_get_output_size, [_NR_cx_blake2b_init2_no_throw] = (unsigned long) cx_blake2b_init2_no_throw, [_NR_cx_blake2b_init_no_throw] = (unsigned long) cx_blake2b_init_no_throw, + [_NR_cx_blake2b_init_key] = (unsigned long) cx_blake2b_init_key, [_NR_cx_blake2b_update] = (unsigned long) cx_blake2b_update, [_NR_cx_cipher_enc_dec] = (unsigned long) cx_cipher_enc_dec, [_NR_cx_cipher_finish] = (unsigned long) cx_cipher_finish, diff --git a/src/cx_hash_iovec.c b/src/cx_hash_iovec.c index 1f79a6c76..cc2a1e35e 100644 --- a/src/cx_hash_iovec.c +++ b/src/cx_hash_iovec.c @@ -203,9 +203,16 @@ cx_err_t cx_shake256_hash_iovec(const cx_iovec_t *iovec, #endif #ifdef HAVE_BLAKE2 -cx_err_t cx_blake2b_256_hash_iovec(const cx_iovec_t *iovec, - size_t iovec_len, - uint8_t digest[static CX_BLAKE2B_256_SIZE]) +cx_err_t cx_blake2b_hash_iovec(const cx_iovec_t *iovec, + size_t iovec_len, + uint8_t *key, + size_t key_len, + uint8_t *salt, + size_t salt_len, + uint8_t *perso, + size_t perso_len, + uint8_t *digest, + size_t digest_len) { #ifdef TARGET_NANOS cx_blake2b_t *hash = &G_cx.blake.blake2b; @@ -214,32 +221,18 @@ cx_err_t cx_blake2b_256_hash_iovec(const cx_iovec_t *iovec, cx_blake2b_t *hash = &blake; #endif - return hash_iovec_ex(&hash->header, - sizeof(cx_blake2b_t), - CX_BLAKE2B, - CX_BLAKE2B_256_SIZE, - iovec, - iovec_len, - digest); -} + cx_err_t error; -cx_err_t cx_blake2b_512_hash_iovec(const cx_iovec_t *iovec, - size_t iovec_len, - uint8_t digest[static CX_BLAKE2B_512_SIZE]) -{ -#ifdef TARGET_NANOS - cx_blake2b_t *hash = &G_cx.blake.blake2b; -#else - cx_blake2b_t blake; - cx_blake2b_t *hash = &blake; -#endif + CX_CHECK(cx_blake2b_init2_no_throw(hash, digest_len * 8, salt, salt_len, perso, perso_len)); + CX_CHECK(cx_blake2b_init_key(hash, key, key_len)); + for (size_t i = 0; i < iovec_len; i++) { + CX_CHECK(cx_hash_update(&hash->header, iovec[i].iov_base, iovec[i].iov_len)); + } + CX_CHECK(cx_hash_final(&hash->header, digest)); - return hash_iovec_ex(&hash->header, - sizeof(cx_blake2b_t), - CX_BLAKE2B, - CX_BLAKE2B_512_SIZE, - iovec, - iovec_len, - digest); +end: + explicit_bzero(hash, sizeof(cx_blake2b_t)); + + return error; } #endif diff --git a/src/cx_stubs.S b/src/cx_stubs.S index 2fdba261d..3a9d22953 100644 --- a/src/cx_stubs.S +++ b/src/cx_stubs.S @@ -43,6 +43,7 @@ CX_TRAMPOLINE _NR_cx_blake2b_final cx_blake2b_final CX_TRAMPOLINE _NR_cx_blake2b_get_output_size cx_blake2b_get_output_size CX_TRAMPOLINE _NR_cx_blake2b_init2_no_throw cx_blake2b_init2_no_throw CX_TRAMPOLINE _NR_cx_blake2b_init_no_throw cx_blake2b_init_no_throw +CX_TRAMPOLINE _NR_cx_blake2b_init_key cx_blake2b_init_key CX_TRAMPOLINE _NR_cx_blake2b_update cx_blake2b_update CX_TRAMPOLINE _NR_cx_cipher_enc_dec cx_cipher_enc_dec CX_TRAMPOLINE _NR_cx_cipher_finish cx_cipher_finish @@ -58,7 +59,7 @@ CX_TRAMPOLINE _NR_cx_crc16 cx_crc16 CX_TRAMPOLINE _NR_cx_crc16_update cx_crc16_update // Disable lib CX CRC32 until it get fixed in the OS. // Meanwhile, it's implemented in cx_wrappers.c -//CX_TRAMPOLINE _NR_cx_crc32 cx_crc32 +//CX_TRAMPOLINE _NR_cx_crc32 cx_crc32 CX_TRAMPOLINE _NR_cx_decode_coord cx_decode_coord CX_TRAMPOLINE _NR_cx_ecdh_no_throw cx_ecdh_no_throw CX_TRAMPOLINE _NR_cx_ecdsa_sign_no_throw cx_ecdsa_sign_no_throw