/* linuxkm_memory.h * * Copyright (C) 2006-2026 wolfSSL Inc. * * This file is part of wolfSSL. * * wolfSSL is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * wolfSSL is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ /* included by wolfssl/wolfcrypt/memory.h */ #ifndef LINUXKM_MEMORY_H #define LINUXKM_MEMORY_H enum wc_reloc_dest_segment { WC_R_SEG_NONE = 1, WC_R_SEG_TEXT, WC_R_SEG_RODATA, WC_R_SEG_RWDATA, WC_R_SEG_BSS, WC_R_SEG_OTHER }; enum wc_reloc_type { WC_R_NONE = 1, WC_R_X86_64_32, WC_R_X86_64_32S, WC_R_X86_64_64, WC_R_X86_64_PC32, WC_R_X86_64_PLT32, WC_R_AARCH64_ABS32, WC_R_AARCH64_ABS64, WC_R_AARCH64_ADD_ABS_LO12_NC, WC_R_AARCH64_ADR_PREL_PG_HI21, WC_R_AARCH64_CALL26, WC_R_AARCH64_JUMP26, WC_R_AARCH64_LDST8_ABS_LO12_NC, WC_R_AARCH64_LDST16_ABS_LO12_NC, WC_R_AARCH64_LDST32_ABS_LO12_NC, WC_R_AARCH64_LDST64_ABS_LO12_NC, WC_R_AARCH64_PREL32, WC_R_ARM_ABS32, WC_R_ARM_PREL31, WC_R_ARM_REL32, WC_R_ARM_THM_CALL, WC_R_ARM_THM_JUMP11, WC_R_ARM_THM_JUMP24, WC_R_ARM_THM_MOVT_ABS, WC_R_ARM_THM_MOVW_ABS_NC }; /* This structure is accessed natively by kernel module glue logic, and also * from outside by linux-fips-hash.c -- pack it, with explicit pad bits, to * remove all doubt about layout. */ struct __attribute__((packed)) wc_reloc_table_ent { unsigned int offset; unsigned int dest_offset; signed int dest_addend; #define WC_RELOC_DEST_SEGMENT_BITS 3 unsigned int dest_segment:WC_RELOC_DEST_SEGMENT_BITS; #define WC_RELOC_TYPE_BITS 5 unsigned int reloc_type:WC_RELOC_TYPE_BITS; unsigned int _pad_bits:(32 - (WC_RELOC_DEST_SEGMENT_BITS + WC_RELOC_TYPE_BITS)); }; #if defined(WC_SYM_RELOC_TABLES) || defined(WC_SYM_RELOC_TABLES_SUPPORT) /* full ELF fencepost representation, to allow wc_reloc_normalize_text() */ struct wc_reloc_table_fenceposts { unsigned long start; unsigned long end; unsigned long len_start; unsigned long len_end; }; #define WC_RELOC_TABLE_FENCEPOSTS_INITIALIZER { \ .start = ~0UL, \ .end = ~0UL, \ .len_start = ~0UL, \ .len_end = ~0UL \ } struct wc_reloc_table_segments { unsigned long start; unsigned long end; struct wc_reloc_table_fenceposts text_reloc_tab; struct wc_reloc_table_fenceposts rodata_reloc_tab; unsigned long text_start; unsigned long text_end; #ifdef HAVE_FIPS unsigned long fips_text_start; unsigned long fips_text_end; #endif /* HAVE_FIPS */ unsigned long rodata_start; unsigned long rodata_end; #ifdef HAVE_FIPS unsigned long fips_rodata_start; unsigned long fips_rodata_end; unsigned long verifyCore_start; unsigned long verifyCore_end; #endif /* HAVE_FIPS */ unsigned long data_start; unsigned long data_end; unsigned long bss_start; unsigned long bss_end; int text_is_live; }; #ifdef HAVE_FIPS #define WC_RELOC_TABLE_SEGMENTS_INITIALIZER { \ .start = ~0UL, \ .end = ~0UL, \ .text_reloc_tab = WC_RELOC_TABLE_FENCEPOSTS_INITIALIZER, \ .rodata_reloc_tab = WC_RELOC_TABLE_FENCEPOSTS_INITIALIZER, \ .text_start = ~0UL, \ .text_end = ~0UL, \ .fips_text_start = ~0UL, \ .fips_text_end = ~0UL, \ .rodata_start = ~0UL, \ .rodata_end = ~0UL, \ .fips_rodata_start = ~0UL, \ .fips_rodata_end = ~0UL, \ .verifyCore_start = ~0UL, \ .verifyCore_end = ~0UL, \ .data_start = ~0UL, \ .data_end = ~0UL, \ .bss_start = ~0UL, \ .bss_end = ~0UL, \ .text_is_live = 0 \ } #else /* !HAVE_FIPS */ #define WC_RELOC_TABLE_SEGMENTS_INITIALIZER { \ .start = ~0UL, \ .end = ~0UL, \ .text_reloc_tab = WC_RELOC_TABLE_FENCEPOSTS_INITIALIZER, \ .rodata_reloc_tab = WC_RELOC_TABLE_FENCEPOSTS_INITIALIZER, \ .text_start = ~0UL, \ .text_end = ~0UL, \ .rodata_start = ~0UL, \ .rodata_end = ~0UL, \ .data_start = ~0UL, \ .data_end = ~0UL, \ .bss_start = ~0UL, \ .bss_end = ~0UL, \ .text_is_live = 0 \ } #endif /* !HAVE_FIPS */ struct wc_reloc_counts { int text; int rodata; int rwdata; int bss; int other; }; #elif defined(HAVE_FIPS) /* barebones FIPS fencepost representation -- no provision for * wc_reloc_normalize_segment() */ struct wc_reloc_table_segments { unsigned long start; unsigned long end; unsigned long fips_text_start; unsigned long fips_text_end; unsigned long fips_rodata_start; unsigned long fips_rodata_end; unsigned long verifyCore_start; unsigned long verifyCore_end; }; #define WC_RELOC_TABLE_SEGMENTS_INITIALIZER { \ .start = ~0UL, \ .end = ~0UL, \ .fips_text_start = ~0UL, \ .fips_text_end = ~0UL, \ .fips_rodata_start = ~0UL, \ .fips_rodata_end = ~0UL, \ .verifyCore_start = ~0UL, \ .verifyCore_end = ~0UL \ } struct wc_reloc_counts { int dummy; }; #endif /* !WC_SYM_RELOC_TABLES && HAVE_FIPS */ #if defined(WC_SYM_RELOC_TABLES) || defined(WC_SYM_RELOC_TABLES_SUPPORT) #ifndef WOLFSSL_SEGMENT_CANONICALIZER_BUFSIZ #define WOLFSSL_SEGMENT_CANONICALIZER_BUFSIZ 8192 #endif #ifndef WOLFSSL_TEXT_SEGMENT_CANONICALIZER_BUFSIZ #define WOLFSSL_TEXT_SEGMENT_CANONICALIZER_BUFSIZ WOLFSSL_SEGMENT_CANONICALIZER_BUFSIZ #endif WOLFSSL_API ssize_t wc_reloc_normalize_segment( const byte *seg_in, size_t *seg_in_out_len, byte *seg_out, ssize_t *cur_index_p, const struct wc_reloc_table_segments *seg_map, struct wc_reloc_counts *reloc_counts); #endif /* WC_SYM_RELOC_TABLES || WC_SYM_RELOC_TABLES_SUPPORT */ #ifdef HAVE_FIPS #if defined(WOLFCRYPT_FIPS_CORE_DYNAMIC_HASH_VALUE) || defined(WOLFCRYPT_FIPS_CORE_DYNAMIC_HASH_VALUE_SUPPORT) typedef int (*wc_fips_verifyCore_hmac_setkey_fn)(void *ctx, const byte *key, word32 key_len); typedef int (*wc_fips_verifyCore_hmac_update_fn)(void *ctx, const byte *in, word32 in_len); typedef int (*wc_fips_verifyCore_hmac_final_fn)(void *ctx, byte *out, word32 out_sz); WOLFSSL_API int wc_fips_generate_hash( const struct wc_reloc_table_segments *seg_map, word32 digest_size, const char *hmac_key_base16, void *hmac_ctx, wc_fips_verifyCore_hmac_setkey_fn hmac_setkey, wc_fips_verifyCore_hmac_update_fn hmac_update, wc_fips_verifyCore_hmac_final_fn hmac_final, char *out, word32 *out_size, struct wc_reloc_counts *reloc_counts); #endif #endif /* HAVE_FIPS */ #endif /* LINUXKM_MEMORY_H */