Merge pull request #10344 from douzzer/20260416-linuxkm-fips-rodata-canonify

20260416-linuxkm-fips-rodata-canonify
This commit is contained in:
lealem47
2026-04-30 10:19:43 -06:00
committed by GitHub
16 changed files with 629 additions and 330 deletions
+2 -2
View File
@@ -118,11 +118,11 @@ ifeq "$(ENABLED_LINUXKM_PIE)" "yes"
ifndef NO_PIE_FLAG
ifeq ($(KERNEL_ARCH),arm)
ifeq ($(intcmp $(VERSION),5,1,0,0),1)
NO_PIE_FLAG :=
NO_PIE_FLAG := 1
$(info Note: disabling -fPIE to avoid R_ARM_REL32 on pre-5.11 target kernel.)
else
ifeq ($(intcmp $(VERSION),5,0,1,0)-$(intcmp $(PATCHLEVEL),11,1,0,0),1-1)
NO_PIE_FLAG :=
NO_PIE_FLAG := 1
$(info Note: disabling -fPIE to avoid R_ARM_REL32 on pre-5.11 target kernel.)
endif
endif
+41 -16
View File
@@ -157,30 +157,48 @@ GENERATE_SECTION_MAP := $(AWK) 'BEGIN { printf("") >ENVIRON["SECTION_MAP"]; } \
}'
GENERATE_RELOC_TAB := $(AWK) ' \
BEGIN { \
n=0; \
function open_seg(seg) { \
seen_seg[seg] = 1; \
printf("%s\n ", \
"WOLFSSL_LOCAL const struct wc_reloc_table_ent wc_linuxkm_pie_" seg "_reloc_tab[] = { "); \
cur_seg = seg; \
} \
function close_cur_seg() { \
print " { .offset = ~0U, .dest_offset = ~0U, .dest_addend = 0, .dest_segment = WC_R_SEG_NONE, .reloc_type = WC_R_NONE } };"; \
print "WOLFSSL_LOCAL const unsigned int wc_linuxkm_pie_" cur_seg "_reloc_tab_length = (unsigned int)(sizeof wc_linuxkm_pie_" cur_seg "_reloc_tab / sizeof wc_linuxkm_pie_" cur_seg "_reloc_tab[0]);"; \
cur_seg = ""; \
} \
BEGIN { \
bad_relocs=0; \
print "\#include <wolfssl/wolfcrypt/libwolfssl_sources.h>"; \
print "\#include <wolfssl/wolfcrypt/memory.h>"; \
printf("%s\n ", \
"WOLFSSL_LOCAL const struct wc_reloc_table_ent wc_linuxkm_pie_reloc_tab[] = { "); \
print ""; \
if ("SECTION_MAP" in ENVIRON) { \
while (getline <ENVIRON["SECTION_MAP"] > 0) \
section_map[$$1] = $$2; \
close(ENVIRON["SECTION_MAP"]); \
} \
} \
/^Relocation section '\''\.rela?\.text_wolfcrypt'\''/ { \
p=1; \
next; \
} \
\
/^Relocation section/ { \
p=0; \
if (cur_seg) { \
close_cur_seg(); \
} \
{ \
if (match($$0, "^Relocation section '\''\\.rela?\\.(text|rodata)_wolfcrypt'\''", a)) {\
open_seg(a[1]); \
next; \
} \
} \
} \
\
{ \
if (! cur_seg) \
next; \
} \
/^0/ { \
if (p) { \
if ($$3 !~ "^(R_X86_64_PLT32|R_X86_64_PC32|R_AARCH64_.*|R_ARM.*)$$") { \
print "Unexpected relocation type:\n" $$0 >"/dev/stderr"; \
if ($$3 !~ "^(R_X86_.*|R_AARCH64_.*|R_ARM.*)$$") { \
print "Unexpected relocation type in " cur_seg ":\n" $$0 >"/dev/stderr"; \
++bad_relocs; \
} \
if ($$5 in section_map) \
@@ -224,15 +242,22 @@ GENERATE_RELOC_TAB := $(AWK) ' \
strtonum("0x" $$4), \
$$6 strtonum("0x" $$7), \
section_tag, reloc_type); \
} \
} \
END { \
if (cur_seg) { \
close_cur_seg(); \
} \
n = split("text rodata", segs, " "); \
for (i = 1; i <= n; ++i) { \
if (! (segs[i] in seen_seg)) { \
open_seg(segs[i]); \
close_cur_seg(); \
} \
} \
if (bad_relocs) { \
print "Found " bad_relocs " unresolvable relocations." >"/dev/stderr"; \
exit(1); \
} \
print " { .offset = ~0U, .dest_offset = ~0U, .dest_addend = 0, .dest_segment = WC_R_SEG_NONE, .reloc_type = WC_R_NONE } };"; \
print "WOLFSSL_LOCAL const unsigned int wc_linuxkm_pie_reloc_tab_length = (unsigned int)(sizeof wc_linuxkm_pie_reloc_tab / sizeof wc_linuxkm_pie_reloc_tab[0]);"; \
}'
ifeq "$(V)" "1"
@@ -384,7 +409,7 @@ $(MODULE_TOP)/libwolfssl-user-build/src/.libs/libwolfssl.so: $(LIBWOLFSSL_NAME).
@ echo 'Using existing Makefile for libwolfssl.so.'
@else
@ echo -n 'Configuring user libwolfssl.so...'
@ $(FRESH_ENV) ./configure $(QFLAG) $(VFLAG) --disable-jobserver --enable-cryptonly --enable-fips="$$FIPS_FLAVOR" CFLAGS='-DWC_SYM_RELOC_TABLES_SUPPORT -DWOLFCRYPT_FIPS_CORE_DYNAMIC_HASH_VALUE -DWOLFSSL_USER_SETTINGS -DWOLFSSL_USER_SETTINGS_ASM' $(if $(HOSTCC),CC='$(HOSTCC)')
@ $(FRESH_ENV) ./configure $(QFLAG) $(VFLAG) --disable-jobserver --enable-cryptonly --enable-fips="$$FIPS_FLAVOR" CFLAGS='-DWC_SYM_RELOC_TABLES_SUPPORT -DWOLFCRYPT_FIPS_CORE_DYNAMIC_HASH_VALUE -DWOLFSSL_USER_SETTINGS -DWOLFSSL_USER_SETTINGS_ASM -DDEBUG_LINUXKM_PIE_SUPPORT' $(if $(HOSTCC),CC='$(HOSTCC)')
@ echo ' done.'
@fi
@echo -n 'Building user libwolfssl.so...'
+8 -4
View File
@@ -48,15 +48,19 @@ fi
# shellcheck disable=SC2016 # using $AWK instead of awk confuses shellcheck.
readarray -t fenceposts < <(readelf --wide --sections --symbols "$mod_path" | "$AWK" '
BEGIN {
fips_fenceposts["wc_linuxkm_pie_reloc_tab"] = "reloc_tab_start";
fips_fenceposts["wc_linuxkm_pie_reloc_tab_length"] = "reloc_tab_len_start";
fips_fenceposts["wc_linuxkm_pie_text_reloc_tab"] = "text_reloc_tab.start";
fips_fenceposts["wc_linuxkm_pie_text_reloc_tab_length"] = "text_reloc_tab.len_start";
fips_fenceposts["wc_linuxkm_pie_rodata_reloc_tab"] = "rodata_reloc_tab.start";
fips_fenceposts["wc_linuxkm_pie_rodata_reloc_tab_length"] = "rodata_reloc_tab.len_start";
fips_fenceposts["verifyCore"] = "verifyCore_start";
fips_fenceposts["wolfCrypt_FIPS_first"] = "fips_text_start";
fips_fenceposts["wolfCrypt_FIPS_last"] = "fips_text_end";
fips_fenceposts["wolfCrypt_FIPS_ro_start"] = "fips_rodata_start";
fips_fenceposts["wolfCrypt_FIPS_ro_end"] = "fips_rodata_end";
singleton_ends["wc_linuxkm_pie_reloc_tab"] = "reloc_tab_end";
singleton_ends["wc_linuxkm_pie_reloc_tab_length"] = "reloc_tab_len_end";
singleton_ends["wc_linuxkm_pie_text_reloc_tab"] = "text_reloc_tab.end";
singleton_ends["wc_linuxkm_pie_text_reloc_tab_length"] = "text_reloc_tab.len_end";
singleton_ends["wc_linuxkm_pie_rodata_reloc_tab"] = "rodata_reloc_tab.end";
singleton_ends["wc_linuxkm_pie_rodata_reloc_tab_length"] = "rodata_reloc_tab.len_end";
singleton_ends["verifyCore"] = "verifyCore_end";
}
+41 -17
View File
@@ -104,10 +104,14 @@ int main(int argc, char **argv)
.val = FENCEPOST_OPT_FLAG | offsetof(typeof(seg_map), x) }
FENCEPOST_OPT(text_start),
FENCEPOST_OPT(text_end),
FENCEPOST_OPT(reloc_tab_start),
FENCEPOST_OPT(reloc_tab_end),
FENCEPOST_OPT(reloc_tab_len_start),
FENCEPOST_OPT(reloc_tab_len_end),
FENCEPOST_OPT(text_reloc_tab.start),
FENCEPOST_OPT(text_reloc_tab.end),
FENCEPOST_OPT(text_reloc_tab.len_start),
FENCEPOST_OPT(text_reloc_tab.len_end),
FENCEPOST_OPT(rodata_reloc_tab.start),
FENCEPOST_OPT(rodata_reloc_tab.end),
FENCEPOST_OPT(rodata_reloc_tab.len_start),
FENCEPOST_OPT(rodata_reloc_tab.len_end),
FENCEPOST_OPT(fips_text_start),
FENCEPOST_OPT(fips_text_end),
FENCEPOST_OPT(rodata_start),
@@ -228,10 +232,14 @@ int main(int argc, char **argv)
if ((seg_map.text_start == ~0UL) ||
(seg_map.text_end == ~0UL) ||
(seg_map.reloc_tab_start == ~0UL) ||
(seg_map.reloc_tab_end == ~0UL) ||
(seg_map.reloc_tab_len_start == ~0UL) ||
(seg_map.reloc_tab_len_end == ~0UL) ||
(seg_map.text_reloc_tab.start == ~0UL) ||
(seg_map.text_reloc_tab.end == ~0UL) ||
(seg_map.text_reloc_tab.len_start == ~0UL) ||
(seg_map.text_reloc_tab.len_end == ~0UL) ||
(seg_map.rodata_reloc_tab.start == ~0UL) ||
(seg_map.rodata_reloc_tab.end == ~0UL) ||
(seg_map.rodata_reloc_tab.len_start == ~0UL) ||
(seg_map.rodata_reloc_tab.len_end == ~0UL) ||
(seg_map.fips_text_start == ~0UL) ||
(seg_map.fips_text_end == ~0UL) ||
(seg_map.rodata_start == ~0UL) ||
@@ -267,12 +275,23 @@ int main(int argc, char **argv)
exit(1);
}
if ((seg_map.reloc_tab_start >= seg_map.reloc_tab_end) ||
(seg_map.reloc_tab_end >= (unsigned long)st.st_size) ||
(seg_map.reloc_tab_len_start >= seg_map.reloc_tab_len_end) ||
(seg_map.reloc_tab_len_end >= (unsigned long)st.st_size))
if ((seg_map.text_reloc_tab.start >= seg_map.text_reloc_tab.end) ||
(seg_map.text_reloc_tab.end >= (unsigned long)st.st_size) ||
(seg_map.text_reloc_tab.len_start >= seg_map.text_reloc_tab.len_end) ||
(seg_map.text_reloc_tab.len_end >= (unsigned long)st.st_size))
{
fprintf(stderr, "%s: supplied reloc_tab fencepost(s) are out of bounds "
fprintf(stderr, "%s: supplied text_reloc_tab fencepost(s) are out of bounds "
"for supplied module %s with length %lu.\n",
progname, mod_path, (unsigned long)st.st_size);
exit(1);
}
if ((seg_map.rodata_reloc_tab.start >= seg_map.rodata_reloc_tab.end) ||
(seg_map.rodata_reloc_tab.end >= (unsigned long)st.st_size) ||
(seg_map.rodata_reloc_tab.len_start >= seg_map.rodata_reloc_tab.len_end) ||
(seg_map.rodata_reloc_tab.len_end >= (unsigned long)st.st_size))
{
fprintf(stderr, "%s: supplied rodata_reloc_tab fencepost(s) are out of bounds "
"for supplied module %s with length %lu.\n",
progname, mod_path, (unsigned long)st.st_size);
exit(1);
@@ -291,10 +310,15 @@ int main(int argc, char **argv)
seg_map.start = (unsigned long)mod_map;
seg_map.end = (unsigned long)mod_map + st.st_size;
seg_map.reloc_tab_start += (unsigned long)mod_map;
seg_map.reloc_tab_end += (unsigned long)mod_map;
seg_map.reloc_tab_len_start += (unsigned long)mod_map;
seg_map.reloc_tab_len_end += (unsigned long)mod_map;
seg_map.text_reloc_tab.start += (unsigned long)mod_map;
seg_map.text_reloc_tab.end += (unsigned long)mod_map;
seg_map.text_reloc_tab.len_start += (unsigned long)mod_map;
seg_map.text_reloc_tab.len_end += (unsigned long)mod_map;
seg_map.rodata_reloc_tab.start += (unsigned long)mod_map;
seg_map.rodata_reloc_tab.end += (unsigned long)mod_map;
seg_map.rodata_reloc_tab.len_start += (unsigned long)mod_map;
seg_map.rodata_reloc_tab.len_end += (unsigned long)mod_map;
seg_map.verifyCore_start += (unsigned long)mod_map;
seg_map.verifyCore_end += (unsigned long)mod_map;
+279 -128
View File
@@ -74,44 +74,41 @@ static const struct reloc_layout_ent {
};
static inline long find_reloc_tab_offset(
const struct wc_reloc_table_segments *seg_map,
const struct wc_reloc_table_ent reloc_tab[],
word32 reloc_tab_len,
size_t text_in_offset)
size_t seg_in_offset)
{
long ret;
unsigned long hop;
if (seg_in_offset >= (size_t)reloc_tab[reloc_tab_len - 1].offset) {
RELOC_DEBUG_PRINTF("ERROR: %s failed.\n", __FUNCTION__);
return BAD_FUNC_ARG;
}
if (reloc_tab_len <= 1) {
RELOC_DEBUG_PRINTF("ERROR: %s failed.\n", __FUNCTION__);
return -1;
}
if (text_in_offset >= (size_t)(seg_map->text_end - seg_map->text_start)) {
RELOC_DEBUG_PRINTF("ERROR: %s failed.\n", __FUNCTION__);
return -1;
}
if (text_in_offset >= (size_t)reloc_tab[reloc_tab_len - 1].offset) {
RELOC_DEBUG_PRINTF("ERROR: %s failed.\n", __FUNCTION__);
return -1;
/* empty relocation table. */
return 0;
}
for (ret = 0,
hop = reloc_tab_len >> 1;
hop;
hop >>= 1)
{
if (text_in_offset == (size_t)reloc_tab[ret].offset)
if (seg_in_offset == (size_t)reloc_tab[ret].offset)
break;
else if (text_in_offset > (size_t)reloc_tab[ret].offset)
else if (seg_in_offset > (size_t)reloc_tab[ret].offset)
ret += hop;
else if (ret)
ret -= hop;
}
while ((ret < (long)reloc_tab_len - 1) &&
((size_t)reloc_tab[ret].offset < text_in_offset))
((size_t)reloc_tab[ret].offset < seg_in_offset))
++ret;
while ((ret > 0) &&
((size_t)reloc_tab[ret - 1].offset >= text_in_offset))
((size_t)reloc_tab[ret - 1].offset >= seg_in_offset))
--ret;
#ifdef DEBUG_LINUXKM_PIE_SUPPORT
@@ -128,35 +125,65 @@ static inline long find_reloc_tab_offset(
#define wc_get_unaligned(v) ({ typeof(*(v)) _v_aligned; XMEMCPY((void *)&_v_aligned, (void *)(v), sizeof _v_aligned); _v_aligned; })
#define wc_put_unaligned(v, v_out) do { typeof(v) _v = (v); XMEMCPY((void *)(v_out), (void *)&_v, sizeof(typeof(*(v_out)))); } while (0)
ssize_t wc_reloc_normalize_text(
const byte *text_in,
size_t text_in_len,
byte *text_out,
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)
{
ssize_t i;
size_t text_in_offset;
size_t seg_in_offset;
const struct wc_reloc_table_ent *last_reloc; /* for error-checking order in reloc_tab[] */
int n_text_r = 0, n_rodata_r = 0, n_rwdata_r = 0, n_bss_r = 0, n_other_r = 0, n_oob_r = 0;
const struct wc_reloc_table_ent *reloc_tab = (const struct wc_reloc_table_ent *)seg_map->reloc_tab_start;
const word32 reloc_tab_len = *(const word32 *)seg_map->reloc_tab_len_start;
const struct wc_reloc_table_ent *reloc_tab;
word32 reloc_tab_len;
uintptr_t src_seg_start;
#ifdef DEBUG_LINUXKM_PIE_SUPPORT
uintptr_t src_seg_end;
const char *src_seg_name;
#endif
if ((text_in_len == 0) ||
((uintptr_t)text_in < seg_map->text_start) ||
((uintptr_t)(text_in + text_in_len) > seg_map->text_end))
if (*seg_in_out_len == 0)
return BAD_FUNC_ARG;
if (((uintptr_t)seg_in >= seg_map->text_start) &&
((uintptr_t)(seg_in + *seg_in_out_len) <= seg_map->text_end))
{
RELOC_DEBUG_PRINTF("ERROR: %s returning -1 with span %llx-%llx versus segment %llx-%llx.\n",
reloc_tab = (const struct wc_reloc_table_ent *)seg_map->text_reloc_tab.start;
reloc_tab_len = *(const word32 *)seg_map->text_reloc_tab.len_start;
src_seg_start = seg_map->text_start;
#ifdef DEBUG_LINUXKM_PIE_SUPPORT
src_seg_end = seg_map->text_end;
src_seg_name = "text";
#endif
}
else if (((uintptr_t)seg_in >= seg_map->rodata_start) &&
((uintptr_t)(seg_in + *seg_in_out_len) <= seg_map->rodata_end))
{
reloc_tab = (const struct wc_reloc_table_ent *)seg_map->rodata_reloc_tab.start;
reloc_tab_len = *(const word32 *)seg_map->rodata_reloc_tab.len_start;
src_seg_start = seg_map->rodata_start;
#ifdef DEBUG_LINUXKM_PIE_SUPPORT
src_seg_end = seg_map->rodata_end;
src_seg_name = "rodata";
#endif
}
else
{
RELOC_DEBUG_PRINTF("ERROR: %s returning BAD_FUNC_ARG with span %llx-%llx versus text %llx-%llx and rodata %llx-%llx.\n",
__FUNCTION__,
(unsigned long long)(uintptr_t)text_in,
(unsigned long long)(uintptr_t)(text_in + text_in_len),
(unsigned long long)(uintptr_t)seg_in,
(unsigned long long)(uintptr_t)(seg_in + *seg_in_out_len),
(unsigned long long)seg_map->text_start,
(unsigned long long)seg_map->text_end);
return -1;
(unsigned long long)seg_map->text_end,
(unsigned long long)seg_map->rodata_start,
(unsigned long long)seg_map->rodata_end);
return BAD_FUNC_ARG;
}
text_in_offset = (uintptr_t)text_in - seg_map->text_start;
seg_in_offset = (uintptr_t)seg_in - src_seg_start;
if (cur_index_p)
i = *cur_index_p;
@@ -164,25 +191,28 @@ ssize_t wc_reloc_normalize_text(
i = -1;
if (i == -1)
i = find_reloc_tab_offset(seg_map, reloc_tab, reloc_tab_len, text_in_offset);
i = find_reloc_tab_offset(reloc_tab, reloc_tab_len, seg_in_offset);
if (i < 0)
return i;
WC_SANITIZE_DISABLE();
memcpy(text_out, text_in, text_in_len);
memcpy(seg_out, seg_in, *seg_in_out_len);
WC_SANITIZE_ENABLE();
/* note, if there are no relocations in the src seg, the loop isn't entered
* at all, and we return without further ado.
*/
for (last_reloc = &reloc_tab[i > 0 ? i-1 : 0];
(size_t)i < reloc_tab_len - 1;
++i)
{
const struct wc_reloc_table_ent *next_reloc = &reloc_tab[i];
enum wc_reloc_dest_segment dest_seg;
uintptr_t seg_beg;
uintptr_t dest_seg_start;
#ifdef DEBUG_LINUXKM_PIE_SUPPORT
uintptr_t seg_end;
const char *seg_name;
uintptr_t dest_seg_end;
const char *dest_seg_name;
#endif
word64 reloc_buf = 0;
const struct reloc_layout_ent *layout;
@@ -196,7 +226,7 @@ ssize_t wc_reloc_normalize_text(
if (last_reloc->offset > next_reloc->offset) {
RELOC_DEBUG_PRINTF("BUG: out-of-order offset found at reloc_tab[%zd]: %u > %u\n",
i, last_reloc->offset, next_reloc->offset);
return -1;
return BAD_FUNC_ARG;
}
last_reloc = next_reloc;
@@ -204,7 +234,7 @@ ssize_t wc_reloc_normalize_text(
if (next_reloc->reloc_type >= (sizeof reloc_layouts / sizeof reloc_layouts[0])) {
RELOC_DEBUG_PRINTF("BUG: unknown relocation type %u found at reloc_tab[%zd]\n",
next_reloc->reloc_type, i);
return -1;
return BAD_FUNC_ARG;
}
layout = &reloc_layouts[next_reloc->reloc_type];
@@ -217,7 +247,7 @@ ssize_t wc_reloc_normalize_text(
default:
RELOC_DEBUG_PRINTF("BUG: unexpected relocation width %llu found at reloc_tab[%lld], reloc type %u\n",
(unsigned long long)layout->width, (long long)i, next_reloc->reloc_type);
return -1;
return BAD_FUNC_ARG;
}
/* provisionally assign the destination segment from the reloc record --
@@ -227,23 +257,23 @@ ssize_t wc_reloc_normalize_text(
dest_seg = next_reloc->dest_segment;
/* next_reloc_rel is the offset of the relocation relative to the start
* of the current text chunk (text_in). i.e., text_in + next_reloc_rel
* of the current text chunk (seg_in). i.e., seg_in + next_reloc_rel
* is the start of the relocation.
*/
next_reloc_rel = next_reloc->offset - text_in_offset;
next_reloc_rel = next_reloc->offset - seg_in_offset;
if (next_reloc_rel >= text_in_len) {
if (next_reloc_rel >= *seg_in_out_len) {
/* no more relocations in this buffer. */
break;
}
if ((text_in_len < WC_BITS_TO_BYTES(layout->width)) ||
(next_reloc_rel > text_in_len - WC_BITS_TO_BYTES(layout->width)))
if ((*seg_in_out_len < WC_BITS_TO_BYTES(layout->width)) ||
(next_reloc_rel > *seg_in_out_len - WC_BITS_TO_BYTES(layout->width)))
{
/* relocation straddles buffer at end -- caller will try again with
* that relocation at the start.
*/
text_in_len = next_reloc_rel;
*seg_in_out_len = next_reloc_rel;
break;
}
@@ -257,61 +287,61 @@ ssize_t wc_reloc_normalize_text(
*/
switch (layout->width) {
case 32:
reloc_buf = (word64)(sword64)(wc_get_unaligned((sword32 *)&text_out[next_reloc_rel]) & (sword32)layout->mask);
reloc_buf = (word64)(sword64)(wc_get_unaligned((sword32 *)&seg_out[next_reloc_rel]) & (sword32)layout->mask);
break;
case 64:
reloc_buf = (word64)(sword64)(wc_get_unaligned((sword64 *)&text_out[next_reloc_rel]) & (sword64)layout->mask);
reloc_buf = (word64)(sword64)(wc_get_unaligned((sword64 *)&seg_out[next_reloc_rel]) & (sword64)layout->mask);
break;
case 16:
reloc_buf = (word64)(sword64)(wc_get_unaligned((sword16 *)&text_out[next_reloc_rel]) & (sword16)layout->mask);
reloc_buf = (word64)(sword64)(wc_get_unaligned((sword16 *)&seg_out[next_reloc_rel]) & (sword16)layout->mask);
break;
}
}
else {
switch (layout->width) {
case 32:
reloc_buf = (word64)(wc_get_unaligned((word32 *)&text_out[next_reloc_rel]) & (word32)layout->mask);
reloc_buf = (word64)(wc_get_unaligned((word32 *)&seg_out[next_reloc_rel]) & (word32)layout->mask);
break;
case 64:
reloc_buf = (word64)(wc_get_unaligned((word64 *)&text_out[next_reloc_rel]) & layout->mask);
reloc_buf = (word64)(wc_get_unaligned((word64 *)&seg_out[next_reloc_rel]) & layout->mask);
break;
case 16:
reloc_buf = (word64)(wc_get_unaligned((word16 *)&text_out[next_reloc_rel]) & (word16)layout->mask);
reloc_buf = (word64)(wc_get_unaligned((word16 *)&seg_out[next_reloc_rel]) & (word16)layout->mask);
break;
}
}
switch (dest_seg) {
case WC_R_SEG_TEXT:
seg_beg = seg_map->text_start;
dest_seg_start = seg_map->text_start;
++n_text_r;
#ifdef DEBUG_LINUXKM_PIE_SUPPORT
seg_end = seg_map->text_end;
seg_name = "text";
dest_seg_end = seg_map->text_end;
dest_seg_name = "text";
#endif
break;
case WC_R_SEG_RODATA:
seg_beg = seg_map->rodata_start;
dest_seg_start = seg_map->rodata_start;
++n_rodata_r;
#ifdef DEBUG_LINUXKM_PIE_SUPPORT
seg_end = seg_map->rodata_end;
seg_name = "rodata";
dest_seg_end = seg_map->rodata_end;
dest_seg_name = "rodata";
#endif
break;
case WC_R_SEG_RWDATA:
seg_beg = seg_map->data_start;
dest_seg_start = seg_map->data_start;
++n_rwdata_r;
#ifdef DEBUG_LINUXKM_PIE_SUPPORT
seg_end = seg_map->data_end;
seg_name = "data";
dest_seg_end = seg_map->data_end;
dest_seg_name = "data";
#endif
break;
case WC_R_SEG_BSS:
seg_beg = seg_map->bss_start;
dest_seg_start = seg_map->bss_start;
++n_bss_r;
#ifdef DEBUG_LINUXKM_PIE_SUPPORT
seg_end = seg_map->bss_end;
seg_name = "bss";
dest_seg_end = seg_map->bss_end;
dest_seg_name = "bss";
#endif
break;
default:
@@ -319,10 +349,10 @@ ssize_t wc_reloc_normalize_text(
dest_seg = WC_R_SEG_OTHER;
FALL_THROUGH;
case WC_R_SEG_OTHER:
seg_beg = 0;
dest_seg_start = 0;
#ifdef DEBUG_LINUXKM_PIE_SUPPORT
seg_end = 0;
seg_name = "other";
dest_seg_end = 0;
dest_seg_name = "other";
#endif
break;
}
@@ -344,33 +374,35 @@ ssize_t wc_reloc_normalize_text(
* baked into the reloc_tab for each relocation.
*/
if (layout->is_relative)
reloc_buf = reloc_buf + (uintptr_t)next_reloc->offset - (uintptr_t)next_reloc->dest_addend - (seg_beg - seg_map->text_start);
reloc_buf = reloc_buf + (uintptr_t)next_reloc->offset - (uintptr_t)next_reloc->dest_addend - (dest_seg_start - src_seg_start);
else
reloc_buf = reloc_buf - seg_beg - (uintptr_t)next_reloc->dest_addend;
reloc_buf = reloc_buf - dest_seg_start - (uintptr_t)next_reloc->dest_addend;
}
else {
reloc_buf = (word64)next_reloc->dest_offset;
}
#ifdef DEBUG_LINUXKM_PIE_SUPPORT
if (reloc_buf >= seg_end - seg_beg) {
if (reloc_buf >= dest_seg_end - dest_seg_start) {
++n_oob_r;
RELOC_DEBUG_PRINTF("WARNING: normalized value is out of bounds (%s0x%llx) at index %lld, text offset 0x%x, reloc type %s, "
"dest seg .%s_wolfcrypt, offset from text to dest segment %s0x%llx, raw dest addr %s0x%llx, "
"seg span 0x%llx - 0x%llx, seg size 0x%llx, text base 0x%llx\n",
RELOC_DEBUG_PRINTF("WARNING: normalized value is out of bounds (%s0x%llx) at index %lld, %s offset 0x%x, reloc type %s, "
"src seg .%s_wolfcrypt, dest seg .%s_wolfcrypt, offset from src to dest segment %s0x%llx, raw dest addr %s0x%llx, "
"seg span 0x%llx - 0x%llx, seg size 0x%llx, src seg 0x%llx-0x%llx\n",
(long long)reloc_buf < 0 ? "-" : "",
(long long)reloc_buf < 0 ? -(long long)reloc_buf : (long long)reloc_buf,
(long long)i,
src_seg_name,
next_reloc->offset,
layout->name,
seg_name,
seg_beg < seg_map->text_start ? "-" : "+",
seg_beg < seg_map->text_start ? (unsigned long long)seg_map->text_start - seg_beg : seg_beg - (unsigned long long)seg_map->text_start,
src_seg_name,
dest_seg_name,
dest_seg_start < src_seg_start ? "-" : "+",
dest_seg_start < src_seg_start ? (unsigned long long)src_seg_start - dest_seg_start : dest_seg_start - (unsigned long long)src_seg_start,
(layout->is_signed && ((long long)raw_dest_addr < 0)) ? "-" : "",
(layout->is_signed && ((long long)raw_dest_addr < 0)) ? (unsigned long long)-(long long)raw_dest_addr : raw_dest_addr,
(unsigned long long)seg_beg,
(unsigned long long)seg_end,
(unsigned long long)(seg_end - seg_beg),
(unsigned long long)seg_map->text_start);
(unsigned long long)dest_seg_start,
(unsigned long long)dest_seg_end,
(unsigned long long)(dest_seg_end - dest_seg_start),
(unsigned long long)src_seg_start, (unsigned long long)src_seg_end);
}
#endif
}
@@ -414,8 +446,8 @@ ssize_t wc_reloc_normalize_text(
break;
default:
RELOC_DEBUG_PRINTF("BUG: unrecognized relocation type %u in reloc record %zu, text offset 0x%x\n",
(unsigned)next_reloc->reloc_type, i, reloc_tab[i].offset);
RELOC_DEBUG_PRINTF("BUG: unrecognized relocation type %u in reloc record %zu, %s offset 0x%x\n",
(unsigned)next_reloc->reloc_type, i, src_seg_name, reloc_tab[i].offset);
++n_oob_r;
dest_seg = WC_R_SEG_OTHER;
}
@@ -427,8 +459,8 @@ ssize_t wc_reloc_normalize_text(
reloc_buf = 0;
++n_other_r;
RELOC_DEBUG_PRINTF("found non-wolfcrypt relocation at index %lld, text offset 0x%x.\n",
(long long)i, reloc_tab[i].offset);
RELOC_DEBUG_PRINTF("found non-wolfcrypt relocation at index %lld, %s offset 0x%x.\n",
(long long)i, src_seg_name, reloc_tab[i].offset);
}
/* xor in a label identifying the dest segment and reloc type. */
@@ -438,13 +470,13 @@ ssize_t wc_reloc_normalize_text(
/* write the modified reloc_buf to the destination buffer. */
switch (layout->width) {
case 32:
wc_put_unaligned((word32)reloc_buf, (word32 *)&text_out[next_reloc_rel]);
wc_put_unaligned((word32)reloc_buf, (word32 *)&seg_out[next_reloc_rel]);
break;
case 64:
wc_put_unaligned(reloc_buf, (word64 *)&text_out[next_reloc_rel]);
wc_put_unaligned(reloc_buf, (word64 *)&seg_out[next_reloc_rel]);
break;
case 16:
wc_put_unaligned((word16)reloc_buf, (word16 *)&text_out[next_reloc_rel]);
wc_put_unaligned((word16)reloc_buf, (word16 *)&seg_out[next_reloc_rel]);
break;
}
}
@@ -458,15 +490,15 @@ ssize_t wc_reloc_normalize_text(
}
if ((n_other_r > 0) || (n_oob_r > 0))
RELOC_DEBUG_PRINTF("text_in=%llx relocs=%d/%d/%d/%d/%d/%d ret = %llu\n",
(unsigned long long)(uintptr_t)text_in, n_text_r, n_rodata_r,
RELOC_DEBUG_PRINTF("seg_in=%llx relocs=%d/%d/%d/%d/%d/%d ret = %llu\n",
(unsigned long long)(uintptr_t)seg_in, n_text_r, n_rodata_r,
n_rwdata_r, n_bss_r, n_other_r, n_oob_r,
(unsigned long long)text_in_len);
(unsigned long long)*seg_in_out_len);
if (cur_index_p)
*cur_index_p = i;
return (ssize_t)text_in_len;
return (ssize_t)*seg_in_out_len;
}
#endif /* WC_SYM_RELOC_TABLES || WC_SYM_RELOC_TABLES_SUPPORT */
@@ -553,16 +585,28 @@ int wc_fips_generate_hash(
#if defined(WC_SYM_RELOC_TABLES) || defined(WC_SYM_RELOC_TABLES_SUPPORT)
if (seg_map->text_is_live) {
if ((seg_map->reloc_tab_start == 0) ||
(seg_map->reloc_tab_len_start == 0))
if ((seg_map->text_reloc_tab.start == 0) ||
(seg_map->text_reloc_tab.len_start == 0))
{
RELOC_DEBUG_PRINTF("assert failed.\n");
return BAD_FUNC_ARG;
}
if ((seg_map->rodata_reloc_tab.start == 0) ||
(seg_map->rodata_reloc_tab.len_start == 0))
{
RELOC_DEBUG_PRINTF("assert failed.\n");
return BAD_FUNC_ARG;
}
}
else {
if ((seg_map->reloc_tab_end == 0) ||
(seg_map->reloc_tab_len_end == 0))
if ((seg_map->text_reloc_tab.end == 0) ||
(seg_map->text_reloc_tab.len_end == 0))
{
RELOC_DEBUG_PRINTF("assert failed.\n");
return BAD_FUNC_ARG;
}
if ((seg_map->rodata_reloc_tab.end == 0) ||
(seg_map->rodata_reloc_tab.len_end == 0))
{
RELOC_DEBUG_PRINTF("assert failed.\n");
return BAD_FUNC_ARG;
@@ -575,8 +619,10 @@ int wc_fips_generate_hash(
(seg_map->fips_rodata_start >= seg_map->fips_rodata_end)
#if defined(WC_SYM_RELOC_TABLES) || defined(WC_SYM_RELOC_TABLES_SUPPORT)
||
((seg_map->reloc_tab_end != 0) && (seg_map->reloc_tab_start >= seg_map->reloc_tab_end)) ||
((seg_map->reloc_tab_len_end != 0) && (seg_map->reloc_tab_len_start >= seg_map->reloc_tab_len_end)) ||
((seg_map->text_reloc_tab.end != 0) && (seg_map->text_reloc_tab.start >= seg_map->text_reloc_tab.end)) ||
((seg_map->text_reloc_tab.len_end != 0) && (seg_map->text_reloc_tab.len_start >= seg_map->text_reloc_tab.len_end)) ||
((seg_map->rodata_reloc_tab.end != 0) && (seg_map->rodata_reloc_tab.start >= seg_map->rodata_reloc_tab.end)) ||
((seg_map->rodata_reloc_tab.len_end != 0) && (seg_map->rodata_reloc_tab.len_start >= seg_map->rodata_reloc_tab.len_end)) ||
(seg_map->text_start >= seg_map->text_end) ||
(seg_map->rodata_start >= seg_map->rodata_end) ||
(seg_map->data_start >= seg_map->data_end) ||
@@ -594,8 +640,10 @@ int wc_fips_generate_hash(
(seg_map->verifyCore_start < seg_map->start)
#if defined(WC_SYM_RELOC_TABLES) || defined(WC_SYM_RELOC_TABLES_SUPPORT)
||
(seg_map->reloc_tab_start < seg_map->start) ||
(seg_map->reloc_tab_len_start < seg_map->start) ||
(seg_map->text_reloc_tab.start < seg_map->start) ||
(seg_map->text_reloc_tab.len_start < seg_map->start) ||
(seg_map->rodata_reloc_tab.start < seg_map->start) ||
(seg_map->rodata_reloc_tab.len_start < seg_map->start) ||
(seg_map->text_start < seg_map->start) ||
(seg_map->rodata_start < seg_map->start) ||
(seg_map->data_start < seg_map->start) ||
@@ -614,10 +662,14 @@ int wc_fips_generate_hash(
(seg_map->verifyCore_end > seg_map->end)
#if defined(WC_SYM_RELOC_TABLES) || defined(WC_SYM_RELOC_TABLES_SUPPORT)
||
((seg_map->reloc_tab_end != 0) &&
(seg_map->reloc_tab_end > seg_map->end)) ||
((seg_map->reloc_tab_len_end != 0) &&
(seg_map->reloc_tab_len_end > seg_map->end)) ||
((seg_map->text_reloc_tab.end != 0) &&
(seg_map->text_reloc_tab.end > seg_map->end)) ||
((seg_map->text_reloc_tab.len_end != 0) &&
(seg_map->text_reloc_tab.len_end > seg_map->end)) ||
((seg_map->rodata_reloc_tab.end != 0) &&
(seg_map->rodata_reloc_tab.end > seg_map->end)) ||
((seg_map->rodata_reloc_tab.len_end != 0) &&
(seg_map->rodata_reloc_tab.len_end > seg_map->end)) ||
(seg_map->text_end > seg_map->end) ||
(seg_map->rodata_end > seg_map->end) ||
(seg_map->data_end > seg_map->end) ||
@@ -631,15 +683,15 @@ int wc_fips_generate_hash(
}
#if defined(WC_SYM_RELOC_TABLES) || defined(WC_SYM_RELOC_TABLES_SUPPORT)
if ((seg_map->reloc_tab_len_end != 0) &&
(seg_map->reloc_tab_len_end - seg_map->reloc_tab_len_start != sizeof(word32)))
if ((seg_map->text_reloc_tab.len_end != 0) &&
(seg_map->text_reloc_tab.len_end - seg_map->text_reloc_tab.len_start != sizeof(word32)))
{
RELOC_DEBUG_PRINTF("assert failed.\n");
return BAD_FUNC_ARG;
}
else if (seg_map->reloc_tab_len_start & (sizeof(word32) - 1)) {
/* fprintf(stderr, "%s: seg_map->reloc_tab_len_start isn't properly aligned: 0x%llx.\n", progname, (
unsigned long long)seg_map->reloc_tab_len_start); */
else if (seg_map->text_reloc_tab.len_start & (sizeof(word32) - 1)) {
/* fprintf(stderr, "%s: seg_map->text_reloc_tab.len_start isn't properly aligned: 0x%llx.\n", progname, (
unsigned long long)seg_map->text_reloc_tab.len_start); */
RELOC_DEBUG_PRINTF("assert failed.\n");
return BAD_ALIGN_E;
}
@@ -649,8 +701,8 @@ int wc_fips_generate_hash(
* a nonsense byte-swapped value, or the final reloc_tab ent has
* nonsense flags.
*/
word32 reloc_tab_len = *(const word32 *)seg_map->reloc_tab_len_start;
const struct wc_reloc_table_ent *reloc_tab = (const struct wc_reloc_table_ent *)seg_map->reloc_tab_start;
word32 reloc_tab_len = *(const word32 *)seg_map->text_reloc_tab.len_start;
const struct wc_reloc_table_ent *reloc_tab = (const struct wc_reloc_table_ent *)seg_map->text_reloc_tab.start;
if (reloc_tab_len == 0) {
RELOC_DEBUG_PRINTF("assert failed.\n");
return BAD_FUNC_ARG;
@@ -667,14 +719,64 @@ int wc_fips_generate_hash(
RELOC_DEBUG_PRINTF("assert failed.\n");
return BAD_FUNC_ARG;
}
else if ((seg_map->reloc_tab_end != 0) &&
(seg_map->reloc_tab_end - seg_map->reloc_tab_start != sizeof(struct wc_reloc_table_ent) * *(const word32 *)seg_map->reloc_tab_len_start))
else if ((seg_map->text_reloc_tab.end != 0) &&
(seg_map->text_reloc_tab.end - seg_map->text_reloc_tab.start != sizeof(struct wc_reloc_table_ent) * *(const word32 *)seg_map->text_reloc_tab.len_start))
{
/*
fprintf(stderr, "%s: wc_linuxkm_pie_reloc_tab_length from module (%u) is inconsistent with actual reloc_tab size %llu.\n",
fprintf(stderr, "%s: wc_linuxkm_pie_text_reloc_tab_length from module (%u) is inconsistent with actual text_reloc_tab size %llu.\n",
progname,
*(const word32 *)seg_map->reloc_tab_len_start,
(unsigned long long)(seg_map->reloc_tab_end - seg_map->reloc_tab_start));
*(const word32 *)seg_map->text_reloc_tab.len_start,
(unsigned long long)(seg_map->text_reloc_tab.end - seg_map->text_reloc_tab.start));
*/
RELOC_DEBUG_PRINTF("assert failed.\n");
return BAD_FUNC_ARG;
}
}
if ((seg_map->rodata_reloc_tab.len_end != 0) &&
(seg_map->rodata_reloc_tab.len_end - seg_map->rodata_reloc_tab.len_start != sizeof(word32)))
{
RELOC_DEBUG_PRINTF("assert failed.\n");
return BAD_FUNC_ARG;
}
else if (seg_map->rodata_reloc_tab.len_start & (sizeof(word32) - 1)) {
/* fprintf(stderr, "%s: seg_map->rodata_reloc_tab.len_start isn't properly aligned: 0x%llx.\n", progname, (
unsigned long long)seg_map->rodata_reloc_tab.len_start); */
RELOC_DEBUG_PRINTF("assert failed.\n");
return BAD_ALIGN_E;
}
else {
/* Note we don't currently handle modules that are endian-conflicted
* with the build host -- that'll be caught here, when reloc_tab_len is
* a nonsense byte-swapped value, or the final reloc_tab ent has
* nonsense flags.
*/
word32 reloc_tab_len = *(const word32 *)seg_map->rodata_reloc_tab.len_start;
const struct wc_reloc_table_ent *reloc_tab = (const struct wc_reloc_table_ent *)seg_map->rodata_reloc_tab.start;
if (reloc_tab_len == 0) {
RELOC_DEBUG_PRINTF("assert failed.\n");
return BAD_FUNC_ARG;
}
else if ((seg_map->end != 0) &&
((unsigned long)(reloc_tab + reloc_tab_len) > seg_map->end))
{
RELOC_DEBUG_PRINTF("assert failed.\n");
return BAD_FUNC_ARG;
}
else if ((reloc_tab[reloc_tab_len - 1].dest_segment != WC_R_SEG_NONE) ||
(reloc_tab[reloc_tab_len - 1].reloc_type != WC_R_NONE))
{
RELOC_DEBUG_PRINTF("assert failed.\n");
return BAD_FUNC_ARG;
}
else if ((seg_map->rodata_reloc_tab.end != 0) &&
(seg_map->rodata_reloc_tab.end - seg_map->rodata_reloc_tab.start != sizeof(struct wc_reloc_table_ent) * *(const word32 *)seg_map->rodata_reloc_tab.len_start))
{
/*
fprintf(stderr, "%s: wc_linuxkm_pie_rodata_reloc_tab_length from module (%u) is inconsistent with actual rodata_reloc_tab size %llu.\n",
progname,
*(const word32 *)seg_map->rodata_reloc_tab.len_start,
(unsigned long long)(seg_map->rodata_reloc_tab.end - seg_map->rodata_reloc_tab.start));
*/
RELOC_DEBUG_PRINTF("assert failed.\n");
return BAD_FUNC_ARG;
@@ -728,9 +830,10 @@ int wc_fips_generate_hash(
#if defined(WC_SYM_RELOC_TABLES) || defined(WC_SYM_RELOC_TABLES_SUPPORT)
{
ssize_t cur_reloc_index = -1;
ssize_t cur_reloc_index;
const byte *text_p = (const byte *)seg_map->fips_text_start;
byte *buf = XMALLOC(WOLFSSL_TEXT_SEGMENT_CANONICALIZER_BUFSIZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
const byte *rodata_p = (const byte *)seg_map->fips_rodata_start;
byte *buf = XMALLOC(WOLFSSL_SEGMENT_CANONICALIZER_BUFSIZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (! buf) {
ret = MEMORY_E;
@@ -738,23 +841,23 @@ int wc_fips_generate_hash(
goto out;
}
cur_reloc_index = -1;
while (text_p < (const byte *)seg_map->fips_text_end) {
/* wc_reloc_normalize_text() does its own WC_SANITIZE_DISABLE()s, so
* we defer it here.
*/
ssize_t progress = wc_reloc_normalize_text(
size_t text_in_out_len = min(WOLFSSL_SEGMENT_CANONICALIZER_BUFSIZ,
(size_t)((const byte *)seg_map->fips_text_end - text_p));
ssize_t progress = wc_reloc_normalize_segment(
text_p,
min(WOLFSSL_TEXT_SEGMENT_CANONICALIZER_BUFSIZ, (word32)((const byte *)seg_map->fips_text_end - text_p)),
&text_in_out_len,
buf,
&cur_reloc_index,
seg_map,
reloc_counts);
if (progress <= 0) {
ret = IN_CORE_FIPS_E;
RELOC_DEBUG_PRINTF("wc_reloc_normalize_text() failed.\n");
RELOC_DEBUG_PRINTF("wc_reloc_normalize_segment() for text failed: %zd.\n", progress);
ret = progress ? (int)progress : IN_CORE_FIPS_E;
break;
}
ret = hmac_update(hmac_ctx, buf, (word32)progress);
ret = hmac_update(hmac_ctx, buf, (word32)text_in_out_len);
if (ret) {
RELOC_DEBUG_PRINTF("hmac_update() failed.\n");
break;
@@ -762,15 +865,61 @@ int wc_fips_generate_hash(
text_p += progress;
}
if (ret) {
XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
goto out;
}
cur_reloc_index = -1;
while (rodata_p < (const byte *)seg_map->fips_rodata_end) {
size_t rodata_in_out_len = min(WOLFSSL_SEGMENT_CANONICALIZER_BUFSIZ,
(size_t)((const byte *)seg_map->fips_rodata_end - rodata_p));
/* don't hash verifyCore or changing verifyCore will change hash */
if ((rodata_p < (const byte *)seg_map->verifyCore_end) &&
(rodata_p + rodata_in_out_len >= (const byte *)seg_map->verifyCore_start))
{
rodata_in_out_len = (size_t)((const byte *)seg_map->verifyCore_start - rodata_p);
if (rodata_in_out_len == 0) {
rodata_p = (const byte *)seg_map->verifyCore_end;
/* force recomputation of relocation offset when skipping
* a span (not processed by wc_reloc_normalize_segment()).
*/
cur_reloc_index = -1;
continue;
}
}
ssize_t progress = wc_reloc_normalize_segment(
rodata_p,
&rodata_in_out_len,
buf,
&cur_reloc_index,
seg_map,
reloc_counts);
if (progress <= 0) {
RELOC_DEBUG_PRINTF("wc_reloc_normalize_segment() for rodata failed: %zd.\n", progress);
ret = progress ? (int)progress : IN_CORE_FIPS_E;
break;
}
ret = hmac_update(hmac_ctx, buf, (word32)rodata_in_out_len);
if (ret) {
RELOC_DEBUG_PRINTF("hmac_update() failed.\n");
break;
}
rodata_p += progress;
}
XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (ret)
goto out;
}
WC_SANITIZE_DISABLE();
#else
#else /* ! (WC_SYM_RELOC_TABLES || WC_SYM_RELOC_TABLES_SUPPORT) */
(void)reloc_counts;
WC_SANITIZE_DISABLE();
ret = hmac_update(hmac_ctx, (byte *)(wc_ptr_t)seg_map->fips_text_start, (word32)(seg_map->fips_text_end - seg_map->fips_text_start));
#endif /* !WOLFSSL_LINUXKM_PIE_REDIRECT_TABLE */
if (ret) {
RELOC_DEBUG_PRINTF("ERROR: hmac_update failed: err %d\n", ret);
@@ -801,6 +950,8 @@ int wc_fips_generate_hash(
goto out;
}
#endif /* ! (WC_SYM_RELOC_TABLES || WC_SYM_RELOC_TABLES_SUPPORT) */
ret = hmac_final(hmac_ctx, hash, digest_size);
if (ret) {
RELOC_DEBUG_PRINTF("ERROR: hmac_final failed: err %d\n", ret);
+31 -19
View File
@@ -80,13 +80,25 @@ struct __attribute__((packed)) wc_reloc_table_ent {
/* 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;
unsigned long reloc_tab_start;
unsigned long reloc_tab_end;
unsigned long reloc_tab_len_start;
unsigned long reloc_tab_len_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
@@ -113,10 +125,8 @@ struct wc_reloc_table_segments {
#define WC_RELOC_TABLE_SEGMENTS_INITIALIZER { \
.start = ~0UL, \
.end = ~0UL, \
.reloc_tab_start = ~0UL, \
.reloc_tab_end = ~0UL, \
.reloc_tab_len_start = ~0UL, \
.reloc_tab_len_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, \
@@ -139,10 +149,8 @@ struct wc_reloc_table_segments {
#define WC_RELOC_TABLE_SEGMENTS_INITIALIZER { \
.start = ~0UL, \
.end = ~0UL, \
.reloc_tab_start = ~0UL, \
.reloc_tab_end = ~0UL, \
.reloc_tab_len_start = ~0UL, \
.reloc_tab_len_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, \
@@ -167,7 +175,7 @@ struct wc_reloc_counts {
#elif defined(HAVE_FIPS)
/* barebones FIPS fencepost representation -- no provision for
* wc_reloc_normalize_text()
* wc_reloc_normalize_segment()
*/
struct wc_reloc_table_segments {
@@ -200,14 +208,18 @@ struct wc_reloc_counts {
#if defined(WC_SYM_RELOC_TABLES) || defined(WC_SYM_RELOC_TABLES_SUPPORT)
#ifndef WOLFSSL_TEXT_SEGMENT_CANONICALIZER_BUFSIZ
#define WOLFSSL_TEXT_SEGMENT_CANONICALIZER_BUFSIZ 8192
#ifndef WOLFSSL_SEGMENT_CANONICALIZER_BUFSIZ
#define WOLFSSL_SEGMENT_CANONICALIZER_BUFSIZ 8192
#endif
WOLFSSL_API ssize_t wc_reloc_normalize_text(
const byte *text_in,
size_t text_in_len,
byte *text_out,
#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);
+26 -5
View File
@@ -876,15 +876,33 @@
__wc_bss_end[];
extern ssize_t wc_linuxkm_normalize_relocations(
const u8 *text_in,
size_t text_in_len,
u8 *text_out,
const u8 *seg_in,
size_t *seg_in_out_len,
u8 *seg_out,
ssize_t *cur_index_p);
extern ssize_t wc_linuxkm_normalize_relocations_noresize(
const u8 *seg_in,
size_t seg_in_len,
u8 *seg_out,
ssize_t *cur_index_p);
#ifndef WOLFSSL_SEGMENT_CANONICALIZER_BUFSIZ
#define WOLFSSL_SEGMENT_CANONICALIZER_BUFSIZ 8192
#endif
#ifndef WOLFSSL_SEGMENT_CANONICALIZER
#define WOLFSSL_SEGMENT_CANONICALIZER(seg_in, seg_in_out_len, seg_out, cur_index_p) \
wc_linuxkm_normalize_relocations(seg_in, seg_in_out_len, seg_out, cur_index_p)
#endif
/* backward-compatible wrappers */
#ifndef WOLFSSL_TEXT_SEGMENT_CANONICALIZER
#define WOLFSSL_TEXT_SEGMENT_CANONICALIZER(text_in, text_in_len, text_out, cur_index_p) \
wc_linuxkm_normalize_relocations(text_in, text_in_len, text_out, cur_index_p)
#define WOLFSSL_TEXT_SEGMENT_CANONICALIZER_BUFSIZ 8192
wc_linuxkm_normalize_relocations_noresize(text_in, text_in_len, text_out, cur_index_p)
#endif
#ifndef WOLFSSL_TEXT_SEGMENT_CANONICALIZER_BUFSIZ
#define WOLFSSL_TEXT_SEGMENT_CANONICALIZER_BUFSIZ WOLFSSL_SEGMENT_CANONICALIZER_BUFSIZ
#endif
#ifdef CONFIG_MIPS
@@ -896,6 +914,7 @@
struct wolfssl_linuxkm_pie_redirect_table {
#ifdef HAVE_FIPS
typeof(wc_linuxkm_normalize_relocations) *wc_linuxkm_normalize_relocations;
typeof(wc_linuxkm_normalize_relocations_noresize) *wc_linuxkm_normalize_relocations_noresize;
#endif
#ifndef __ARCH_MEMCMP_NO_REDIRECT
@@ -1234,6 +1253,8 @@
#ifdef HAVE_FIPS
#define wc_linuxkm_normalize_relocations \
WC_PIE_INDIRECT_SYM(wc_linuxkm_normalize_relocations)
#define wc_linuxkm_normalize_relocations_noresize \
WC_PIE_INDIRECT_SYM(wc_linuxkm_normalize_relocations_noresize)
#endif
#ifndef __ARCH_MEMCMP_NO_REDIRECT
+23 -23
View File
@@ -347,7 +347,7 @@ static int km_dh_decode_secret(const u8 * buf, unsigned int len,
if (secret.len != expected_len) {
#ifdef WOLFKM_DEBUG_DH
pr_err("%s: km_dh_decode_secret: got %d, expected %zu",
pr_err("%s: km_dh_decode_secret: got %d, expected %zu\n",
WOLFKM_DH_DRIVER, secret.len, expected_len);
#endif /* WOLFKM_DEBUG_DH */
return -EINVAL;
@@ -413,7 +413,7 @@ static int km_dh_alloc_keys(struct km_dh_ctx * ctx)
alloc_keys_end:
if (err) {
#ifdef WOLFKM_DEBUG_DH
pr_err("%s: km_dh_alloc_keys failed: %d",
pr_err("%s: km_dh_alloc_keys failed: %d\n",
WOLFKM_DH_DRIVER, err);
#endif
km_dh_clear_keys(ctx);
@@ -478,7 +478,7 @@ static int km_dh_set_secret(struct crypto_kpp *tfm, const void *buf,
if (km_dh_decode_secret(buf, len, &params) < 0) {
#ifdef WOLFKM_DEBUG_DH
pr_err("%s: dh_set_secret: decode secret failed: %d",
pr_err("%s: dh_set_secret: decode secret failed: %d\n",
WOLFKM_DH_DRIVER, params.key_size);
#endif /* WOLFKM_DEBUG_DH */
err = -EINVAL;
@@ -488,7 +488,7 @@ static int km_dh_set_secret(struct crypto_kpp *tfm, const void *buf,
/* the key, p, and g, must all be provided for normal dh. */
if (!params.key || !params.key_size || !params.p_size || !params.g_size) {
#ifdef WOLFKM_DEBUG_DH
pr_err("%s: dh_set_secret: empty params", WOLFKM_DH_DRIVER);
pr_err("%s: dh_set_secret: empty params\n", WOLFKM_DH_DRIVER);
#endif
err = -EINVAL;
goto dh_secret_end;
@@ -496,7 +496,7 @@ static int km_dh_set_secret(struct crypto_kpp *tfm, const void *buf,
if (params.key_size > params.p_size || params.g_size > params.p_size) {
#ifdef WOLFKM_DEBUG_DH
pr_err("%s: dh_set_secret: invalid params", WOLFKM_DH_DRIVER);
pr_err("%s: dh_set_secret: invalid params\n", WOLFKM_DH_DRIVER);
#endif
err = -EINVAL;
goto dh_secret_end;
@@ -518,7 +518,7 @@ static int km_dh_set_secret(struct crypto_kpp *tfm, const void *buf,
if (err) {
#ifdef WOLFKM_DEBUG_DH
pr_err("%s: wc_DhSetKey failed: %d", WOLFKM_DH_DRIVER, err);
pr_err("%s: wc_DhSetKey failed: %d\n", WOLFKM_DH_DRIVER, err);
#endif
err = -EINVAL;
goto dh_secret_end;
@@ -530,7 +530,7 @@ static int km_dh_set_secret(struct crypto_kpp *tfm, const void *buf,
if (err) {
#ifdef WOLFKM_DEBUG_DH
pr_err("%s: wc_DhImportKeyPair failed: %d", WOLFKM_DH_DRIVER, err);
pr_err("%s: wc_DhImportKeyPair failed: %d\n", WOLFKM_DH_DRIVER, err);
#endif
err = -EINVAL;
goto dh_secret_end;
@@ -585,7 +585,7 @@ static int km_ffdhe_set_secret(struct crypto_kpp *tfm, const void *buf,
if (err) {
#ifdef WOLFKM_DEBUG_DH
pr_err("%s: ffdhe_set_secret: decode secret failed: %d",
pr_err("%s: ffdhe_set_secret: decode secret failed: %d\n",
WOLFKM_DH_DRIVER, params.key_size);
#endif /* WOLFKM_DEBUG_DH */
err = -EINVAL;
@@ -595,7 +595,7 @@ static int km_ffdhe_set_secret(struct crypto_kpp *tfm, const void *buf,
/* p_size and g_size should be 0 for ffdhe. */
if (params.p_size || params.g_size) {
#ifdef WOLFKM_DEBUG_DH
pr_err("%s: ffdhe_set_secret: unexpected p, g params: %d, %d",
pr_err("%s: ffdhe_set_secret: unexpected p, g params: %d, %d\n",
WOLFKM_DH_DRIVER, params.p_size, params.g_size);
#endif /* WOLFKM_DEBUG_DH */
err = -EINVAL;
@@ -616,7 +616,7 @@ static int km_ffdhe_set_secret(struct crypto_kpp *tfm, const void *buf,
if (!params.key_size) {
/* generate the ffdhe key pair*/
#ifdef WOLFKM_DEBUG_DH
pr_info("ffdhe gen key pair");
pr_info("ffdhe gen key pair\n");
#endif
PRIVATE_KEY_UNLOCK();
err = wc_DhGenerateKeyPair(ctx->key, &ctx->rng,
@@ -626,7 +626,7 @@ static int km_ffdhe_set_secret(struct crypto_kpp *tfm, const void *buf,
if (err) {
#ifdef WOLFKM_DEBUG_DH
pr_err("%s: wc_DhGenerateKeyPair failed: %d",
pr_err("%s: wc_DhGenerateKeyPair failed: %d\n",
WOLFKM_DH_DRIVER, err);
#endif
err = -EINVAL;
@@ -641,7 +641,7 @@ static int km_ffdhe_set_secret(struct crypto_kpp *tfm, const void *buf,
if (ctx->pub_len < (ctx->nbits / WOLFSSL_BIT_SIZE)) {
word32 pad_len = ctx->nbits / WOLFSSL_BIT_SIZE - ctx->pub_len;
#ifdef WOLFKM_DEBUG_DH
pr_info("info: km_ffdhe_set_secret: pub key padding %d", pad_len);
pr_info("info: km_ffdhe_set_secret: pub key padding %d\n", pad_len);
#endif
memmove(ctx->pub_key + pad_len, ctx->pub_key, ctx->pub_len);
@@ -660,7 +660,7 @@ static int km_ffdhe_set_secret(struct crypto_kpp *tfm, const void *buf,
if (err) {
#ifdef WOLFKM_DEBUG_DH
pr_err("%s: wc_DhImportKeyPair failed: %d",
pr_err("%s: wc_DhImportKeyPair failed: %d\n",
WOLFKM_DH_DRIVER, err);
#endif
err = -EINVAL;
@@ -783,7 +783,7 @@ static int km_ffdhe_init(struct crypto_kpp *tfm, int name, word32 nbits)
}
#ifdef WOLFKM_DEBUG_DH
pr_info("info: exiting km_dh_init: name %d, nbits %d",
pr_info("info: exiting km_dh_init: name %d, nbits %d\n",
ctx->name, ctx->nbits);
#endif /* WOLFKM_DEBUG_DH */
return 0;
@@ -874,7 +874,7 @@ static int km_dh_gen_pub(struct kpp_request *req)
if (ctx->pub_len > req->dst_len) {
#ifdef WOLFKM_DEBUG_DH
pr_err("error: dst_len too small: %d", req->dst_len);
pr_err("error: dst_len too small: %d\n", req->dst_len);
#endif /* WOLFKM_DEBUG_DH */
req->dst_len = ctx->pub_len;
return -EOVERFLOW;
@@ -885,7 +885,7 @@ static int km_dh_gen_pub(struct kpp_request *req)
err = 0;
#ifdef WOLFKM_DEBUG_DH
pr_info("info: exiting km_dh_gen_pub: %d", ctx->pub_len);
pr_info("info: exiting km_dh_gen_pub: %d\n", ctx->pub_len);
#endif /* WOLFKM_DEBUG_DH */
return err;
}
@@ -921,7 +921,7 @@ static int km_dh_compute_shared_secret(struct kpp_request *req)
if (req->src_len <= 0 || req->src_len > (ctx->nbits / WOLFSSL_BIT_SIZE)) {
#ifdef WOLFKM_DEBUG_DH
pr_err("error: got src_len %d, expected %d", req->src_len,
pr_err("error: got src_len %d, expected %d\n", req->src_len,
(ctx->nbits / WOLFSSL_BIT_SIZE));
#endif /* WOLFKM_DEBUG_DH */
err = -EINVAL;
@@ -2903,7 +2903,7 @@ static int linuxkm_test_kpp_driver(const char * driver,
dst_buf = malloc(dst_len);
if (dst_buf == NULL) {
pr_err("error: allocating out buf failed");
pr_err("error: allocating out buf failed\n");
test_rc = MEMORY_E;
goto test_kpp_end;
}
@@ -2917,20 +2917,20 @@ static int linuxkm_test_kpp_driver(const char * driver,
err = crypto_kpp_generate_public_key(req);
if (err) {
pr_err("error: crypto_kpp_generate_public_key returned: %d", err);
pr_err("error: crypto_kpp_generate_public_key returned: %d\n", err);
test_rc = BAD_FUNC_ARG;
goto test_kpp_end;
}
if (memcmp(expected_a_pub, sg_virt(req->dst), pub_len)) {
pr_err("error: crypto_kpp_generate_public_key: wrong output");
pr_err("error: crypto_kpp_generate_public_key: wrong output\n");
test_rc = WC_KEY_MISMATCH_E;
goto test_kpp_end;
}
src_buf = malloc(src_len);
if (src_buf == NULL) {
pr_err("error: allocating in buf failed");
pr_err("error: allocating in buf failed\n");
test_rc = MEMORY_E;
goto test_kpp_end;
}
@@ -2945,13 +2945,13 @@ static int linuxkm_test_kpp_driver(const char * driver,
err = crypto_kpp_compute_shared_secret(req);
if (err) {
pr_err("error: crypto_kpp_compute_shared_secret returned: %d", err);
pr_err("error: crypto_kpp_compute_shared_secret returned: %d\n", err);
test_rc = BAD_FUNC_ARG;
goto test_kpp_end;
}
if (memcmp(shared_secret, sg_virt(req->dst), shared_s_len)) {
pr_err("error: shared secret does not match");
pr_err("error: shared secret does not match\n");
test_rc = BAD_FUNC_ARG;
goto test_kpp_end;
}
+14 -14
View File
@@ -199,7 +199,7 @@ static int km_ecdh_decode_secret(const u8 * buf, unsigned int len,
if (secret.len != expected_len) {
#ifdef WOLFKM_DEBUG_ECDH
pr_err("%s: km_ecdh_decode_secret: got %d, expected %zu",
pr_err("%s: km_ecdh_decode_secret: got %d, expected %zu\n",
WOLFKM_ECDH_DRIVER, secret.len, expected_len);
#endif /* WOLFKM_DEBUG_ECDH */
return -EINVAL;
@@ -249,7 +249,7 @@ static int km_ecdh_set_secret(struct crypto_kpp *tfm, const void *buf,
if (km_ecdh_decode_secret(buf, len, &params) < 0) {
#ifdef WOLFKM_DEBUG_ECDH
pr_err("%s: ecdh_set_secret: decode secret failed: %d",
pr_err("%s: ecdh_set_secret: decode secret failed: %d\n",
WOLFKM_ECDH_DRIVER, params.key_size);
#endif /* WOLFKM_DEBUG_ECDH */
return -EINVAL;
@@ -417,7 +417,7 @@ static int km_ecdh_init(struct crypto_kpp *tfm, int curve_id)
#endif /* ECC_TIMING_RESISTANT */
#ifdef WOLFKM_DEBUG_ECDH
pr_info("info: exiting km_ecdh_init: curve_id %d, curve_len %d",
pr_info("info: exiting km_ecdh_init: curve_id %d, curve_len %d\n",
ctx->curve_id, ctx->curve_len);
#endif /* WOLFKM_DEBUG_ECDH */
return 0;
@@ -484,7 +484,7 @@ static int km_ecdh_gen_pub(struct kpp_request *req)
if (raw_pub_len > req->dst_len) {
#ifdef WOLFKM_DEBUG_ECDH
pr_err("error: dst_len too small: %d", req->dst_len);
pr_err("error: dst_len too small: %d\n", req->dst_len);
#endif /* WOLFKM_DEBUG_ECDH */
err = -EOVERFLOW;
goto ecdh_gen_pub_end;
@@ -504,7 +504,7 @@ static int km_ecdh_gen_pub(struct kpp_request *req)
err = wc_ecc_make_pub(ctx->key, NULL);
if (err) {
#ifdef WOLFKM_DEBUG_ECDH
pr_err("error: ecc_make_pub returned: %d", err);
pr_err("error: ecc_make_pub returned: %d\n", err);
#endif /* WOLFKM_DEBUG_ECDH */
goto ecdh_gen_pub_end;
}
@@ -522,7 +522,7 @@ static int km_ecdh_gen_pub(struct kpp_request *req)
if (err || pub_x_len != ctx->curve_len || pub_y_len != ctx->curve_len) {
#ifdef WOLFKM_DEBUG_ECDH
pr_err("error: ecc export pub returned: err=%d, x=%d, y=%d", err,
pr_err("error: ecc export pub returned: err=%d, x=%d, y=%d\n", err,
pub_x_len, pub_y_len);
#endif /* WOLFKM_DEBUG_ECDH */
err = -EINVAL;
@@ -537,7 +537,7 @@ ecdh_gen_pub_end:
if (pub) { free(pub); pub = NULL; }
#ifdef WOLFKM_DEBUG_ECDH
pr_info("info: exiting km_ecdh_gen_pub: %d", err);
pr_info("info: exiting km_ecdh_gen_pub: %d\n", err);
#endif /* WOLFKM_DEBUG_ECDH */
return err;
}
@@ -584,7 +584,7 @@ static int km_ecdh_compute_shared_secret(struct kpp_request *req)
if (req->src_len != raw_pub_len) {
#ifdef WOLFKM_DEBUG_ECDH
pr_err("error: got src_len %d, expected %d", req->src_len, raw_pub_len);
pr_err("error: got src_len %d, expected %d\n", req->src_len, raw_pub_len);
#endif /* WOLFKM_DEBUG_ECDH */
err = -EINVAL;
goto ecdh_shared_secret_end;
@@ -928,7 +928,7 @@ static int linuxkm_test_ecdh_nist_driver(const char * driver,
dst_buf = malloc(dst_len);
if (dst_buf == NULL) {
pr_err("error: allocating out buf failed");
pr_err("error: allocating out buf failed\n");
test_rc = BAD_FUNC_ARG;
goto test_ecdh_nist_end;
}
@@ -942,20 +942,20 @@ static int linuxkm_test_ecdh_nist_driver(const char * driver,
err = crypto_kpp_generate_public_key(req);
if (err) {
pr_err("error: crypto_kpp_generate_public_key returned: %d", err);
pr_err("error: crypto_kpp_generate_public_key returned: %d\n", err);
test_rc = BAD_FUNC_ARG;
goto test_ecdh_nist_end;
}
if (memcmp(expected_a_pub, sg_virt(req->dst), pub_len)) {
pr_err("error: crypto_kpp_generate_public_key: wrong output");
pr_err("error: crypto_kpp_generate_public_key: wrong output\n");
test_rc = BAD_FUNC_ARG;
goto test_ecdh_nist_end;
}
src_buf = malloc(src_len);
if (src_buf == NULL) {
pr_err("error: allocating in buf failed");
pr_err("error: allocating in buf failed\n");
test_rc = MEMORY_E;
goto test_ecdh_nist_end;
}
@@ -970,13 +970,13 @@ static int linuxkm_test_ecdh_nist_driver(const char * driver,
err = crypto_kpp_compute_shared_secret(req);
if (err) {
pr_err("error: crypto_kpp_compute_shared_secret returned: %d", err);
pr_err("error: crypto_kpp_compute_shared_secret returned: %d\n", err);
test_rc = BAD_FUNC_ARG;
goto test_ecdh_nist_end;
}
if (memcmp(shared_secret, sg_virt(req->dst), shared_s_len)) {
pr_err("error: shared secret does not match");
pr_err("error: shared secret does not match\n");
test_rc = BAD_FUNC_ARG;
goto test_ecdh_nist_end;
}
+11 -11
View File
@@ -244,7 +244,7 @@ static ssize_t install_algs_handler(struct kobject *kobj, struct kobj_attribute
if (kstrtoint(buf, 10, &arg) || arg != 1)
return -EINVAL;
pr_info("wolfCrypt: Installing algorithms");
pr_info("wolfCrypt: Installing algorithms\n");
ret = linuxkm_lkcapi_register();
if (ret != 0)
@@ -265,7 +265,7 @@ static ssize_t deinstall_algs_handler(struct kobject *kobj, struct kobj_attribut
if (kstrtoint(buf, 10, &arg) || arg != 1)
return -EINVAL;
pr_info("wolfCrypt: Deinstalling algorithms");
pr_info("wolfCrypt: Deinstalling algorithms\n");
ret = linuxkm_lkcapi_unregister();
if (ret != 0)
@@ -274,7 +274,7 @@ static ssize_t deinstall_algs_handler(struct kobject *kobj, struct kobj_attribut
#if defined(HAVE_FIPS) && defined(CONFIG_CRYPTO_MANAGER) && \
!defined(CONFIG_CRYPTO_MANAGER_DISABLE_TESTS)
if (enabled_fips) {
pr_info("wolfCrypt: restoring fips_enabled to off.");
pr_info("wolfCrypt: restoring fips_enabled to off.\n");
enabled_fips = fips_enabled = 0;
}
#endif
@@ -358,7 +358,7 @@ static int linuxkm_lkcapi_register(void)
/* assert system-wide FIPS status, to disable FIPS-forbidden
* test vectors and fuzzing from the CRYPTO_MANAGER.
*/
pr_info("wolfCrypt: changing fips_enabled from 0 to 1 for FIPS module.");
pr_info("wolfCrypt: changing fips_enabled from 0 to 1 for FIPS module.\n");
enabled_fips = fips_enabled = 1;
}
#endif
@@ -382,7 +382,7 @@ static int linuxkm_lkcapi_register(void)
if (! ((alg).base.cra_flags & CRYPTO_ALG_DEAD)) { \
pr_err("ERROR: alg %s not _DEAD " \
"after crypto_unregister_%s -- " \
"marking as loaded despite test failure.", \
"marking as loaded despite test failure.\n", \
(alg).base.cra_driver_name, \
#alg_class); \
alg ## _loaded = 1; \
@@ -434,7 +434,7 @@ static int linuxkm_lkcapi_register(void)
if (! ((alg).base.cra_flags & CRYPTO_ALG_DEAD)) { \
pr_err("ERROR: alg %s not _DEAD " \
"after crypto_unregister_%s -- " \
"marking as loaded despite test failure.", \
"marking as loaded despite test failure.\n", \
(alg).base.cra_driver_name, \
#alg_class); \
alg ## _loaded = 1; \
@@ -729,7 +729,7 @@ static int linuxkm_lkcapi_register(void)
disable_setkey_warnings = 0;
#endif
pr_info("wolfCrypt: %d algorithm%s registered.", linuxkm_lkcapi_n_registered,
pr_info("wolfCrypt: %d algorithm%s registered.\n", linuxkm_lkcapi_n_registered,
linuxkm_lkcapi_n_registered == 1 ? "" : "s");
if (ret == -1) {
@@ -794,7 +794,7 @@ static int linuxkm_lkcapi_unregister(void)
do { \
if (alg ## _loaded) { \
if ((alg).base.cra_flags & CRYPTO_ALG_DEAD) { \
pr_err("alg %s already CRYPTO_ALG_DEAD.", \
pr_err("alg %s already CRYPTO_ALG_DEAD.\n", \
(alg).base.cra_driver_name); \
alg ## _loaded = 0; \
++n_deregistered; \
@@ -807,7 +807,7 @@ static int linuxkm_lkcapi_unregister(void)
if (! ((alg).base.cra_flags & CRYPTO_ALG_DEAD)) { \
pr_err("ERROR: alg %s not _DEAD after " \
"crypto_unregister_%s -- " \
"leaving marked as loaded.", \
"leaving marked as loaded.\n", \
(alg).base.cra_driver_name, \
#alg_class); \
seen_err = -EBUSY; \
@@ -817,7 +817,7 @@ static int linuxkm_lkcapi_unregister(void)
} \
} \
else { \
pr_err("alg %s cannot be uninstalled (refcnt = %d)", \
pr_err("alg %s cannot be uninstalled (refcnt = %d)\n", \
(alg).base.cra_driver_name, cur_refcnt); \
if (cur_refcnt > 0) { seen_err = -EBUSY; } \
} \
@@ -1025,7 +1025,7 @@ static int linuxkm_lkcapi_unregister(void)
#undef UNREGISTER_ALG
linuxkm_lkcapi_n_registered -= n_deregistered;
pr_info("wolfCrypt: %d algorithm%s deregistered, %d remain%s registered.",
pr_info("wolfCrypt: %d algorithm%s deregistered, %d remain%s registered.\n",
n_deregistered, n_deregistered == 1 ? "" : "s",
linuxkm_lkcapi_n_registered, linuxkm_lkcapi_n_registered == 1 ? "s" : "");
+9 -9
View File
@@ -1172,7 +1172,7 @@ pkcs1pad_sign_out:
#ifdef WOLFKM_DEBUG_RSA
pr_info("info: exiting km_pkcs1pad_sign msg_len %d, enc_msg_len %d,"
" sig_len %d, err %d", req->src_len, enc_len, sig_len, err);
" sig_len %d, err %d\n", req->src_len, enc_len, sig_len, err);
#endif /* WOLFKM_DEBUG_RSA */
return err;
}
@@ -1223,7 +1223,7 @@ static int km_pkcs1pad_verify(struct akcipher_request *req)
hash_enc_len = get_hash_enc_len(ctx->hash_oid);
if (hash_enc_len <= 0) {
#ifdef WOLFKM_DEBUG_RSA
pr_err("error: %s: bad hash enc len %d",
pr_err("error: %s: bad hash enc len %d\n",
WOLFKM_RSA_DRIVER, hash_enc_len);
#endif /* WOLFKM_DEBUG_RSA */
err = -EINVAL;
@@ -1233,7 +1233,7 @@ static int km_pkcs1pad_verify(struct akcipher_request *req)
if (msg_len != ctx->digest_len || sig_len != ctx->key_len) {
/* invalid src or dst args */
#ifdef WOLFKM_DEBUG_RSA
pr_err("error: %s: got msg_len %d, expected %d",
pr_err("error: %s: got msg_len %d, expected %d\n",
WOLFKM_RSA_DRIVER, msg_len, ctx->digest_len);
#endif /* WOLFKM_DEBUG_RSA */
err = -EINVAL;
@@ -1287,7 +1287,7 @@ pkcs1pad_verify_out:
#ifdef WOLFKM_DEBUG_RSA
pr_info("info: exiting km_pkcs1pad_verify msg_len %d, enc_msg_len %d,"
" sig_len %d, err %d", msg_len, enc_msg_len, sig_len, err);
" sig_len %d, err %d\n", msg_len, enc_msg_len, sig_len, err);
#endif /* WOLFKM_DEBUG_RSA */
return err;
}
@@ -1420,7 +1420,7 @@ pkcs1_sign_out:
#ifdef WOLFKM_DEBUG_RSA
pr_info("info: exiting km_pkcs1_sign msg_len %d, enc_msg_len %d,"
" sig_len %d, err %d", slen, enc_msg_len, sig_len, err);
" sig_len %d, err %d\n", slen, enc_msg_len, sig_len, err);
#endif /* WOLFKM_DEBUG_RSA */
return err;
}
@@ -1474,7 +1474,7 @@ static int km_pkcs1_verify(struct crypto_sig *tfm,
hash_enc_len = get_hash_enc_len(ctx->hash_oid);
if (hash_enc_len <= 0) {
#ifdef WOLFKM_DEBUG_RSA
pr_err("error: %s: bad hash enc len %d",
pr_err("error: %s: bad hash enc len %d\n",
WOLFKM_RSA_DRIVER, hash_enc_len);
#endif /* WOLFKM_DEBUG_RSA */
err = -EINVAL;
@@ -1484,7 +1484,7 @@ static int km_pkcs1_verify(struct crypto_sig *tfm,
if (msg_len != ctx->digest_len || sig_len != ctx->key_len) {
/* invalid src or dst args */
#ifdef WOLFKM_DEBUG_RSA
pr_err("error: %s: got msg_len %d, expected %d",
pr_err("error: %s: got msg_len %d, expected %d\n",
WOLFKM_RSA_DRIVER, msg_len, ctx->digest_len);
#endif /* WOLFKM_DEBUG_RSA */
err = -EINVAL;
@@ -1538,7 +1538,7 @@ pkcs1_verify_out:
#ifdef WOLFKM_DEBUG_RSA
pr_info("info: exiting km_pkcs1_verify msg_len %d, enc_msg_len %d,"
" sig_len %d, err %d", msg_len, enc_msg_len, sig_len, err);
" sig_len %d, err %d\n", msg_len, enc_msg_len, sig_len, err);
#endif /* WOLFKM_DEBUG_RSA */
return err;
}
@@ -1817,7 +1817,7 @@ pkcs1_dec_out:
if (dec != NULL) { free(dec); dec = NULL; }
#ifdef WOLFKM_DEBUG_RSA
pr_info("info: exiting km_pkcs1pad_dec %d", err);
pr_info("info: exiting km_pkcs1pad_dec %d\n", err);
#endif /* WOLFKM_DEBUG_RSA */
return err;
}
+42 -42
View File
@@ -1188,7 +1188,7 @@ static int wc_linuxkm_drbg_generate(struct wc_rng_bank *ctx,
struct wc_rng_bank_inst *drbg = linuxkm_get_drbg(ctx);
if (! drbg) {
pr_err_once("BUG: linuxkm_get_drbg() failed.");
pr_err_once("BUG: linuxkm_get_drbg() failed.\n");
return -EFAULT;
}
@@ -1235,11 +1235,11 @@ static int wc_linuxkm_drbg_generate(struct wc_rng_bank *ctx,
WC_RNG_BANK_FLAG_CAN_WAIT);
if (ret == 0) {
pr_warn("WARNING: reinitialized DRBG #%d after RNG_FAILURE_E from wc_RNG_GenerateBlock().", raw_smp_processor_id());
pr_warn("WARNING: reinitialized DRBG #%d after RNG_FAILURE_E from wc_RNG_GenerateBlock().\n", raw_smp_processor_id());
continue;
}
else {
pr_warn_once("ERROR: reinitialization of DRBG #%d after RNG_FAILURE_E failed with ret %d.", raw_smp_processor_id(), ret);
pr_warn_once("ERROR: reinitialization of DRBG #%d after RNG_FAILURE_E failed with ret %d.\n", raw_smp_processor_id(), ret);
ret = -EINVAL;
break;
}
@@ -1264,7 +1264,7 @@ static int wc_linuxkm_drbg_generate_tfm(struct crypto_rng *tfm,
{
if (tfm->base.__crt_alg->cra_init != wc_linuxkm_drbg_init_tfm)
{
pr_err_once("BUG: mismatched tfm.");
pr_err_once("BUG: mismatched tfm.\n");
return -EFAULT;
}
@@ -1294,7 +1294,7 @@ static int wc_linuxkm_drbg_seed_tfm(struct crypto_rng *tfm,
{
if (tfm->base.__crt_alg->cra_init != wc_linuxkm_drbg_init_tfm)
{
pr_err_once("BUG: mismatched tfm.");
pr_err_once("BUG: mismatched tfm.\n");
return -EFAULT;
}
@@ -1354,7 +1354,7 @@ static int wc__get_random_bytes(void *buf, size_t len)
NULL, 0, buf, len);
(void)wc_rng_bank_default_checkin(&current_default_wc_rng_bank);
if (ret) {
pr_warn("BUG: wc__get_random_bytes falling through to native get_random_bytes with wc_linuxkm_drbg_default_instance_registered, ret=%d.", ret);
pr_warn("BUG: wc__get_random_bytes falling through to native get_random_bytes with wc_linuxkm_drbg_default_instance_registered, ret=%d.\n", ret);
}
return ret;
}
@@ -1383,7 +1383,7 @@ static ssize_t wc_get_random_bytes_user(struct iov_iter *iter) {
ret = wc_linuxkm_drbg_generate(current_default_wc_rng_bank,
NULL, 0, block, sizeof block);
if (unlikely(ret != 0)) {
pr_err("ERROR: wc_get_random_bytes_user() wc_linuxkm_drbg_generate() returned %d.", ret);
pr_err("ERROR: wc_get_random_bytes_user() wc_linuxkm_drbg_generate() returned %d.\n", ret);
break;
}
@@ -1445,7 +1445,7 @@ static ssize_t wc_extract_crng_user(void __user *buf, size_t nbytes) {
ret = wc_linuxkm_drbg_generate(current_default_wc_rng_bank,
NULL, 0, block, sizeof block);
if (unlikely(ret != 0)) {
pr_err("ERROR: wc_extract_crng_user() wc_linuxkm_drbg_generate() returned %d.", ret);
pr_err("ERROR: wc_extract_crng_user() wc_linuxkm_drbg_generate() returned %d.\n", ret);
break;
}
@@ -1610,10 +1610,10 @@ static int wc_get_random_bytes_by_kprobe(struct kprobe *p, struct pt_regs *regs)
regs->ip = (unsigned long)p->addr + p->ainsn.size;
return 1; /* Handled. */
}
pr_warn("BUG: wc_get_random_bytes_by_kprobe falling through to native get_random_bytes with wc_linuxkm_drbg_default_instance_registered, ret=%d.", ret);
pr_warn("BUG: wc_get_random_bytes_by_kprobe falling through to native get_random_bytes with wc_linuxkm_drbg_default_instance_registered, ret=%d.\n", ret);
}
else
pr_warn("BUG: wc_get_random_bytes_by_kprobe called without wc_linuxkm_drbg_default_instance_registered.");
pr_warn("BUG: wc_get_random_bytes_by_kprobe called without wc_linuxkm_drbg_default_instance_registered.\n");
/* Not handled. Fall through to native implementation, given
* that the alternative is an immediate kernel panic.
@@ -1668,7 +1668,7 @@ static int wc_get_random_bytes_user_kretprobe_enter(struct kretprobe_instance *p
byte block[WC_SHA256_BLOCK_SIZE];
if (unlikely(!wc_linuxkm_drbg_default_instance_registered)) {
pr_warn("BUG: wc_get_random_bytes_user_kretprobe_enter() without wc_linuxkm_drbg_default_instance_registered.");
pr_warn("BUG: wc_get_random_bytes_user_kretprobe_enter() without wc_linuxkm_drbg_default_instance_registered.\n");
ret = -ENOENT;
goto out;
}
@@ -1681,7 +1681,7 @@ static int wc_get_random_bytes_user_kretprobe_enter(struct kretprobe_instance *p
for (;;) {
ret = crypto_rng_get_bytes(crypto_default_rng, block, sizeof block);
if (ret != 0) {
pr_err("ERROR: wc_get_random_bytes_user_kretprobe_enter() crypto_rng_get_bytes() returned %d.", ret);
pr_err("ERROR: wc_get_random_bytes_user_kretprobe_enter() crypto_rng_get_bytes() returned %d.\n", ret);
break;
}
@@ -1714,7 +1714,7 @@ out:
if ((ret != 0) && (this_copied == (size_t)(-1L))) {
/* crypto_rng_get_bytes() failed on the first call, before any update to the iov_iter. */
pr_warn("WARNING: wc_get_random_bytes_user_kretprobe_enter() falling through to native get_random_bytes_user().");
pr_warn("WARNING: wc_get_random_bytes_user_kretprobe_enter() falling through to native get_random_bytes_user().\n");
return -EFAULT;
}
@@ -1741,7 +1741,7 @@ static int wc_get_random_bytes_user_kretprobe_exit(struct kretprobe_instance *p,
struct wc_get_random_bytes_user_kretprobe_ctx *ctx = (struct wc_get_random_bytes_user_kretprobe_ctx *)p->data;
if (unlikely(!wc_linuxkm_drbg_default_instance_registered)) {
pr_warn("BUG: wc_get_random_bytes_user_kretprobe_exit without wc_linuxkm_drbg_default_instance_registered.");
pr_warn("BUG: wc_get_random_bytes_user_kretprobe_exit without wc_linuxkm_drbg_default_instance_registered.\n");
return -EFAULT;
}
@@ -1777,7 +1777,7 @@ static int wc_linuxkm_drbg_startup(void)
int ret;
if (wc_linuxkm_drbg_loaded) {
pr_err("ERROR: wc_linuxkm_drbg_set_default called with wc_linuxkm_drbg_loaded.");
pr_err("ERROR: wc_linuxkm_drbg_set_default called with wc_linuxkm_drbg_loaded.\n");
return -EBUSY;
}
@@ -1791,7 +1791,7 @@ static int wc_linuxkm_drbg_startup(void)
ret = crypto_register_rng(&wc_linuxkm_drbg);
if (ret != 0) {
pr_err("ERROR: crypto_register_rng: %d", ret);
pr_err("ERROR: crypto_register_rng: %d\n", ret);
return ret;
}
@@ -1860,7 +1860,7 @@ static int wc_linuxkm_drbg_startup(void)
}
if (ret)
pr_err("ERROR: wc_linuxkm_drbg_startup: PRNG quality test failed, block length %d, iters %d, ret %d",
pr_err("ERROR: wc_linuxkm_drbg_startup: PRNG quality test failed, block length %d, iters %d, ret %d\n",
i, j, ret);
}
}
@@ -1890,7 +1890,7 @@ static int wc_linuxkm_drbg_startup(void)
ret = crypto_del_default_rng();
if (ret) {
wc_linuxkm_rng_initing_default_bank_flag = 0;
pr_err("ERROR: crypto_del_default_rng returned %d", ret);
pr_err("ERROR: crypto_del_default_rng returned %d\n", ret);
return ret;
}
@@ -1899,27 +1899,27 @@ static int wc_linuxkm_drbg_startup(void)
wc_linuxkm_rng_initing_default_bank_flag = 0;
if (ret) {
pr_err("ERROR: crypto_get_default_rng returned %d", ret);
pr_err("ERROR: crypto_get_default_rng returned %d\n", ret);
return ret;
}
{
int cur_refcnt = WC_LKM_REFCOUNT_TO_INT(wc_linuxkm_drbg.base.cra_refcnt);
if (cur_refcnt < 2) {
pr_err("ERROR: wc_linuxkm_drbg refcnt = %d after crypto_get_default_rng()", cur_refcnt);
pr_err("ERROR: wc_linuxkm_drbg refcnt = %d after crypto_get_default_rng()\n", cur_refcnt);
crypto_put_default_rng();
return -EINVAL;
}
}
if (! crypto_default_rng) {
pr_err("ERROR: crypto_default_rng is null");
pr_err("ERROR: crypto_default_rng is null\n");
crypto_put_default_rng();
return -EINVAL;
}
if (crypto_default_rng->base.__crt_alg->cra_init != wc_linuxkm_drbg_init_tfm) {
pr_err("ERROR: %s NOT registered as systemwide default stdrng -- found \"%s\".", wc_linuxkm_drbg.base.cra_driver_name, crypto_tfm_alg_driver_name(&crypto_default_rng->base));
pr_err("ERROR: %s NOT registered as systemwide default stdrng -- found \"%s\".\n", wc_linuxkm_drbg.base.cra_driver_name, crypto_tfm_alg_driver_name(&crypto_default_rng->base));
crypto_put_default_rng();
return -EINVAL;
}
@@ -1935,7 +1935,7 @@ static int wc_linuxkm_drbg_startup(void)
ret = crypto_del_default_rng();
if (ret) {
wc_linuxkm_rng_initing_default_bank_flag = 0;
pr_err("ERROR: crypto_del_default_rng returned %d", ret);
pr_err("ERROR: crypto_del_default_rng returned %d\n", ret);
return ret;
}
@@ -1944,7 +1944,7 @@ static int wc_linuxkm_drbg_startup(void)
wc_linuxkm_rng_initing_default_bank_flag = 0;
if (ret) {
pr_err("ERROR: __crypto_stdrng_get_bytes returned %d", ret);
pr_err("ERROR: __crypto_stdrng_get_bytes returned %d\n", ret);
return ret;
}
}
@@ -1954,7 +1954,7 @@ static int wc_linuxkm_drbg_startup(void)
ret = wc_linuxkm_rng_bank_init(&default_bank);
wc_linuxkm_rng_initing_default_bank_flag = 0;
if (ret) {
pr_err("ERROR: wc_linuxkm_rng_bank_init returned %d", ret);
pr_err("ERROR: wc_linuxkm_rng_bank_init returned %d\n", ret);
return ret;
}
default_bank_inited = 1;
@@ -1966,11 +1966,11 @@ static int wc_linuxkm_drbg_startup(void)
struct wc_rng_bank *current_default_wc_rng_bank;
ret = wc_rng_bank_default_checkout(&current_default_wc_rng_bank);
if (ret)
pr_err("ERROR: wc_rng_bank_default_checkout() after default stdrng registration returned %d", ret);
pr_err("ERROR: wc_rng_bank_default_checkout() after default stdrng registration returned %d\n", ret);
else {
ret = wc_rng_bank_default_checkin(&current_default_wc_rng_bank);
if (ret)
pr_err("ERROR: wc_rng_bank_default_checkin() after wc_rng_bank_default_checkout() returned %d", ret);
pr_err("ERROR: wc_rng_bank_default_checkin() after wc_rng_bank_default_checkout() returned %d\n", ret);
}
if (ret != 0) {
#if defined(LINUXKM_LKCAPI_REGISTER_HASH_DRBG_DEFAULT) && \
@@ -1986,8 +1986,8 @@ static int wc_linuxkm_drbg_startup(void)
}
wc_linuxkm_drbg_default_instance_registered = 1;
pr_info("%s registered as systemwide default stdrng.", wc_linuxkm_drbg.base.cra_driver_name);
pr_info("libwolfssl: to unload module, first echo 1 > /sys/module/libwolfssl/deinstall_algs");
pr_info("%s registered as systemwide default stdrng.\n", wc_linuxkm_drbg.base.cra_driver_name);
pr_info("libwolfssl: to unload module, first echo 1 > /sys/module/libwolfssl/deinstall_algs\n");
#ifdef LINUXKM_DRBG_GET_RANDOM_BYTES
@@ -1999,7 +1999,7 @@ static int wc_linuxkm_drbg_startup(void)
if (ret == 0) {
wc_get_random_bytes_callbacks_installed = 1;
pr_info("libwolfssl: kernel global random_bytes handlers installed.");
pr_info("libwolfssl: kernel global random_bytes handlers installed.\n");
}
else {
pr_err("ERROR: wolfssl_linuxkm_register_random_bytes_handlers() failed: %d\n", ret);
@@ -2039,22 +2039,22 @@ static int wc_linuxkm_drbg_startup(void)
byte scratch[4];
ret = wc__get_random_bytes(scratch, sizeof(scratch));
if (ret != 0) {
pr_err("ERROR: wc__get_random_bytes() returned %d", ret);
pr_err("ERROR: wc__get_random_bytes() returned %d\n", ret);
return -EINVAL;
}
ret = wc_mix_pool_bytes(scratch, sizeof(scratch));
if (ret != 0) {
pr_err("ERROR: wc_mix_pool_bytes() returned %d", ret);
pr_err("ERROR: wc_mix_pool_bytes() returned %d\n", ret);
return -EINVAL;
}
ret = wc_crng_reseed();
if (ret != 0) {
pr_err("ERROR: wc_crng_reseed() returned %d", ret);
pr_err("ERROR: wc_crng_reseed() returned %d\n", ret);
return -EINVAL;
}
ret = wc__get_random_bytes(scratch, sizeof(scratch));
if (ret != 0) {
pr_err("ERROR: wc__get_random_bytes() returned %d", ret);
pr_err("ERROR: wc__get_random_bytes() returned %d\n", ret);
return -EINVAL;
}
}
@@ -2071,7 +2071,7 @@ static int wc_linuxkm_drbg_cleanup(void) {
int cur_refcnt;
if (! wc_linuxkm_drbg_loaded) {
pr_err("ERROR: wc_linuxkm_drbg_cleanup called with ! wc_linuxkm_drbg_loaded");
pr_err("ERROR: wc_linuxkm_drbg_cleanup called with ! wc_linuxkm_drbg_loaded\n");
return -EINVAL;
}
@@ -2094,7 +2094,7 @@ static int wc_linuxkm_drbg_cleanup(void) {
if (wc_get_random_bytes_callbacks_installed) {
ret = wolfssl_linuxkm_unregister_random_bytes_handlers();
if (ret != 0) {
pr_err("ERROR: wolfssl_linuxkm_unregister_random_bytes_handlers returned %d", ret);
pr_err("ERROR: wolfssl_linuxkm_unregister_random_bytes_handlers returned %d\n", ret);
return ret;
}
pr_info("libwolfssl: kernel global random_bytes handlers uninstalled\n");
@@ -2127,7 +2127,7 @@ static int wc_linuxkm_drbg_cleanup(void) {
#if LINUX_VERSION_CODE < KERNEL_VERSION(7, 1, 0)
ret = crypto_del_default_rng();
if (ret) {
pr_err("ERROR: crypto_del_default_rng failed: %d", ret);
pr_err("ERROR: crypto_del_default_rng failed: %d\n", ret);
return ret;
}
#else /* >= 7.1.0 */
@@ -2136,7 +2136,7 @@ static int wc_linuxkm_drbg_cleanup(void) {
if (fips_enabled) {
ret = crypto_del_default_rng();
if (ret) {
pr_err("ERROR: crypto_del_default_rng failed: %d", ret);
pr_err("ERROR: crypto_del_default_rng failed: %d\n", ret);
return ret;
}
}
@@ -2145,11 +2145,11 @@ static int wc_linuxkm_drbg_cleanup(void) {
if (default_bank_inited) {
ret = wc_rng_bank_default_clear(&default_bank);
if (ret)
pr_err("ERROR: wc_rng_bank_default_clear in wc_linuxkm_drbg_cleanup failed: %d", ret);
pr_err("ERROR: wc_rng_bank_default_clear in wc_linuxkm_drbg_cleanup failed: %d\n", ret);
else {
ret = wc_rng_bank_fini(&default_bank);
if (ret)
pr_err("ERROR: wc_rng_bank_fini in wc_linuxkm_drbg_cleanup failed: %d", ret);
pr_err("ERROR: wc_rng_bank_fini in wc_linuxkm_drbg_cleanup failed: %d\n", ret);
}
default_bank_inited = 0;
}
@@ -2162,14 +2162,14 @@ static int wc_linuxkm_drbg_cleanup(void) {
cur_refcnt = WC_LKM_REFCOUNT_TO_INT(wc_linuxkm_drbg.base.cra_refcnt);
if (cur_refcnt != 1) {
pr_err("ERROR: wc_linuxkm_drbg_cleanup called with refcnt = %d", cur_refcnt);
pr_err("ERROR: wc_linuxkm_drbg_cleanup called with refcnt = %d\n", cur_refcnt);
return -EBUSY;
}
crypto_unregister_rng(&wc_linuxkm_drbg);
if (! (wc_linuxkm_drbg.base.cra_flags & CRYPTO_ALG_DEAD)) {
pr_warn("WARNING: wc_linuxkm_drbg_cleanup: after crypto_unregister_rng, wc_linuxkm_drbg isn't dead.");
pr_warn("WARNING: wc_linuxkm_drbg_cleanup: after crypto_unregister_rng, wc_linuxkm_drbg isn't dead.\n");
return -EBUSY;
}
+90 -28
View File
@@ -621,7 +621,7 @@ static int wolfssl_init(void)
#ifdef HAVE_FIPS
/* The compiled-in verifycore must be the right length, else the module
* geometry will change when the correct value is passed in, destabilizing
* wc_linuxkm_pie_reloc_tab. It also must be the right length for the
* wc_linuxkm_pie_text_reloc_tab. It also must be the right length for the
* module-update-fips-hash recipe (in-place overwrite) to work, and for
* updateFipsHash() (WOLFCRYPT_FIPS_CORE_DYNAMIC_HASH_VALUE) to be safe from
* overruns.
@@ -711,28 +711,32 @@ static int wolfssl_init(void)
{
unsigned int text_hash = hash_span((const u8 *)__wc_text_start, (const u8 *)__wc_text_end, 1);
unsigned int rodata_hash = hash_span((const u8 *)__wc_rodata_start, (const u8 *)__wc_rodata_end, 1);
u8 *canon_buf = malloc(WOLFSSL_TEXT_SEGMENT_CANONICALIZER_BUFSIZ);
ssize_t cur_reloc_index = -1;
u8 *canon_buf = malloc(WOLFSSL_SEGMENT_CANONICALIZER_BUFSIZ);
ssize_t cur_reloc_index;
const u8 *text_p = (const u8 *)__wc_text_start;
const u8 *rodata_p = (const u8 *)__wc_rodata_start;
unsigned int stabilized_text_hash = 1;
unsigned int stabilized_rodata_hash = 1;
if (! canon_buf) {
pr_err("ERROR: malloc(%d) for WOLFSSL_TEXT_SEGMENT_CANONICALIZER failed: %ld.\n", WOLFSSL_TEXT_SEGMENT_CANONICALIZER_BUFSIZ, PTR_ERR(canon_buf));
pr_err("ERROR: malloc(%d) for WOLFSSL_*_SEGMENT_CANONICALIZER failed: %ld.\n", WOLFSSL_SEGMENT_CANONICALIZER_BUFSIZ, PTR_ERR(canon_buf));
return -ECANCELED;
}
reloc_counts.text = reloc_counts.rodata = reloc_counts.rwdata = reloc_counts.bss =
reloc_counts.other = 0;
cur_reloc_index = -1;
while (text_p < (const u8 *)__wc_text_end) {
size_t text_in_out_len = min(WOLFSSL_SEGMENT_CANONICALIZER_BUFSIZ,
(size_t)((const u8 *)__wc_text_end - text_p));
ssize_t progress =
WOLFSSL_TEXT_SEGMENT_CANONICALIZER(
WOLFSSL_SEGMENT_CANONICALIZER(
text_p,
min(WOLFSSL_TEXT_SEGMENT_CANONICALIZER_BUFSIZ,
(word32)((const u8 *)__wc_text_end - text_p)),
&text_in_out_len,
canon_buf, &cur_reloc_index);
if (progress <= 0) {
pr_err("ERROR: progress=%ld from WOLFSSL_TEXT_SEGMENT_CANONICALIZER() at offset %x (text=%x-%x).\n",
pr_err("ERROR: progress=%ld from WOLFSSL_SEGMENT_CANONICALIZER() at offset %x (text=%x-%x).\n",
(long)progress,
(unsigned)(uintptr_t)text_p,
(unsigned)(uintptr_t)__wc_text_start,
@@ -740,10 +744,33 @@ static int wolfssl_init(void)
free(canon_buf);
return -ECANCELED;
}
stabilized_text_hash = hash_span(canon_buf, canon_buf + progress, stabilized_text_hash);
stabilized_text_hash = hash_span(canon_buf, canon_buf + text_in_out_len, stabilized_text_hash);
text_p += progress;
}
/* note verifyCore is hashed along with the rest of .rodata_wolfcrypt. */
cur_reloc_index = -1;
while (rodata_p < (const u8 *)__wc_rodata_end) {
size_t rodata_in_out_len = min(WOLFSSL_SEGMENT_CANONICALIZER_BUFSIZ,
(size_t)((const u8 *)__wc_rodata_end - rodata_p));
ssize_t progress =
WOLFSSL_SEGMENT_CANONICALIZER(
rodata_p,
&rodata_in_out_len,
canon_buf, &cur_reloc_index);
if (progress <= 0) {
pr_err("ERROR: progress=%ld from WOLFSSL_SEGMENT_CANONICALIZER() at offset %x (rodata=%x-%x).\n",
(long)progress,
(unsigned)(uintptr_t)rodata_p,
(unsigned)(uintptr_t)__wc_rodata_start,
(unsigned)(uintptr_t)__wc_rodata_end);
free(canon_buf);
return -ECANCELED;
}
stabilized_rodata_hash = hash_span(canon_buf, canon_buf + rodata_in_out_len, stabilized_rodata_hash);
rodata_p += progress;
}
free(canon_buf);
canon_buf = 0;
@@ -751,12 +778,13 @@ static int wolfssl_init(void)
* the true module start address, which is potentially useful to an
* attacker.
*/
pr_info("wolfCrypt segment hashes (spans): text 0x%x (%llu), rodata 0x%x (%llu), offset %c0x%llx, canon text 0x%x\n",
pr_info("wolfCrypt segment hashes (spans): text 0x%x (%llu), rodata 0x%x (%llu), offset %c0x%llx, canon text 0x%x, canon rodata 0x%x\n",
text_hash, (unsigned long long)((uintptr_t)__wc_text_end - (uintptr_t)__wc_text_start),
rodata_hash, (unsigned long long)((uintptr_t)__wc_rodata_end - (uintptr_t)__wc_rodata_start),
(uintptr_t)__wc_text_start < (uintptr_t)&__wc_rodata_start[0] ? '+' : '-',
(uintptr_t)__wc_text_start < (uintptr_t)&__wc_rodata_start[0] ? (unsigned long long)((uintptr_t)&__wc_rodata_start[0] - (uintptr_t)__wc_text_start) : (unsigned long long)((uintptr_t)__wc_text_start - (uintptr_t)&__wc_rodata_start[0]),
stabilized_text_hash);
stabilized_text_hash,
stabilized_rodata_hash);
pr_info("wolfCrypt segments: text=%llx-%llx, rodata=%llx-%llx, "
"rwdata=%llx-%llx, bss=%llx-%llx\n",
@@ -1090,7 +1118,7 @@ static void wolfssl_exit(void)
pr_err("ERROR: wc_RunAllCast_fips() failed at shutdown with return value %d\n", ret);
}
else
pr_info("wolfCrypt FIPS re-self-test succeeded at unload: all algorithms re-verified.");
pr_info("wolfCrypt FIPS re-self-test succeeded at unload: all algorithms re-verified.\n");
#endif
(void)libwolfssl_cleanup();
@@ -1118,17 +1146,23 @@ MODULE_VERSION(LIBWOLFSSL_VERSION_STRING);
#ifdef WC_SYM_RELOC_TABLES
extern const struct wc_reloc_table_ent wc_linuxkm_pie_reloc_tab[];
extern const unsigned int wc_linuxkm_pie_reloc_tab_length;
extern const struct wc_reloc_table_ent wc_linuxkm_pie_text_reloc_tab[];
extern const unsigned int wc_linuxkm_pie_text_reloc_tab_length;
extern const struct wc_reloc_table_ent wc_linuxkm_pie_rodata_reloc_tab[];
extern const unsigned int wc_linuxkm_pie_rodata_reloc_tab_length;
static const struct wc_reloc_table_segments seg_map = {
.start = 0, .end = 0,
.text_start = (size_t)(uintptr_t)__wc_text_start,
.text_end = (size_t)(uintptr_t)__wc_text_end,
.reloc_tab_start = (size_t)(uintptr_t)wc_linuxkm_pie_reloc_tab,
.reloc_tab_end = 0,
.reloc_tab_len_start = (size_t)(uintptr_t)&wc_linuxkm_pie_reloc_tab_length,
.reloc_tab_len_end = 0,
.text_reloc_tab.start = (size_t)(uintptr_t)wc_linuxkm_pie_text_reloc_tab,
.text_reloc_tab.end = 0,
.text_reloc_tab.len_start = (size_t)(uintptr_t)&wc_linuxkm_pie_text_reloc_tab_length,
.text_reloc_tab.len_end = 0,
.rodata_reloc_tab.start = (size_t)(uintptr_t)wc_linuxkm_pie_rodata_reloc_tab,
.rodata_reloc_tab.end = 0,
.rodata_reloc_tab.len_start = (size_t)(uintptr_t)&wc_linuxkm_pie_rodata_reloc_tab_length,
.rodata_reloc_tab.len_end = 0,
#ifdef HAVE_FIPS
#ifdef WC_USE_PIE_FENCEPOSTS_FOR_FIPS
.fips_text_start = (size_t)(uintptr_t)__wc_text_start,
@@ -1161,12 +1195,12 @@ static const struct wc_reloc_table_segments seg_map = {
};
ssize_t wc_linuxkm_normalize_relocations(
const u8 *text_in,
size_t text_in_len,
u8 *text_out,
const u8 *seg_in,
size_t *seg_in_out_len,
u8 *seg_out,
ssize_t *cur_index_p)
{
return wc_reloc_normalize_text(text_in, text_in_len, text_out, cur_index_p, &seg_map,
return wc_reloc_normalize_segment(seg_in, seg_in_out_len, seg_out, cur_index_p, &seg_map,
#ifdef DEBUG_LINUXKM_PIE_SUPPORT
&reloc_counts
#else
@@ -1175,6 +1209,28 @@ ssize_t wc_linuxkm_normalize_relocations(
);
}
ssize_t wc_linuxkm_normalize_relocations_noresize(
const u8 *seg_in,
size_t seg_in_len,
u8 *seg_out,
ssize_t *cur_index_p)
{
ssize_t ret;
ret = wc_reloc_normalize_segment(seg_in, &seg_in_len, seg_out, cur_index_p, &seg_map,
#ifdef DEBUG_LINUXKM_PIE_SUPPORT
&reloc_counts
#else
NULL
#endif
);
if (ret < 0)
return ret;
if ((size_t)ret != seg_in_len)
return -EINVAL;
else
return seg_in_len;
}
#elif defined(HAVE_FIPS)
static const struct wc_reloc_table_segments seg_map = {
@@ -1227,6 +1283,8 @@ static int set_up_wolfssl_linuxkm_pie_redirect_table(void) {
#ifdef HAVE_FIPS
wolfssl_linuxkm_pie_redirect_table.wc_linuxkm_normalize_relocations =
wc_linuxkm_normalize_relocations;
wolfssl_linuxkm_pie_redirect_table.wc_linuxkm_normalize_relocations_noresize =
wc_linuxkm_normalize_relocations_noresize;
#endif
#ifndef __ARCH_MEMCMP_NO_REDIRECT
@@ -1717,7 +1775,7 @@ static int updateFipsHash(void)
size_t desc_size = crypto_shash_descsize(tfm) + sizeof *desc;
desc = XMALLOC(desc_size, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (desc == NULL) {
pr_err("ERROR: failed allocating desc.");
pr_err("ERROR: failed allocating desc.\n");
ret = MEMORY_E;
goto out;
}
@@ -1790,13 +1848,17 @@ static WC_MAYBE_UNUSED void *my_kallsyms_lookup_name(const char *name) {
int ret;
kallsyms_lookup_name_kp.addr = NULL;
if ((ret = register_kprobe(&kallsyms_lookup_name_kp)) != 0) {
pr_err_once("ERROR: register_kprobe(&kallsyms_lookup_name_kp) failed: %d", ret);
#ifdef WOLFSSL_LINUXKM_VERBOSE_DEBUG
pr_err_once("ERROR: register_kprobe(&kallsyms_lookup_name_kp) failed: %d\n", ret);
#endif
return 0;
}
kallsyms_lookup_name_ptr = (typeof(kallsyms_lookup_name_ptr))kallsyms_lookup_name_kp.addr;
unregister_kprobe(&kallsyms_lookup_name_kp);
if (! kallsyms_lookup_name_ptr) {
pr_err_once("ERROR: kallsyms_lookup_name_kp.addr is null.");
#ifdef WOLFSSL_LINUXKM_VERBOSE_DEBUG
pr_err_once("ERROR: kallsyms_lookup_name_kp.addr is null.\n");
#endif
return 0;
}
}
@@ -1825,7 +1887,7 @@ static ssize_t FIPS_rerun_self_test_handler(struct kobject *kobj, struct kobj_at
return -EINVAL;
}
pr_info("wolfCrypt: rerunning FIPS self-test on command.");
pr_info("wolfCrypt: rerunning FIPS self-test on command.\n");
if (WC_SIG_IGNORE_BEGIN() >= 0) {
ret = wolfCrypt_IntegrityTest_fips();
@@ -1836,7 +1898,7 @@ static ssize_t FIPS_rerun_self_test_handler(struct kobject *kobj, struct kobj_at
ret = -1;
}
if (ret != 0) {
pr_err("ERROR: wolfCrypt_IntegrityTest_fips: error %d", ret);
pr_err("ERROR: wolfCrypt_IntegrityTest_fips: error %d\n", ret);
return -EINVAL;
}
@@ -1855,7 +1917,7 @@ static ssize_t FIPS_rerun_self_test_handler(struct kobject *kobj, struct kobj_at
return -EINVAL;
}
pr_info("wolfCrypt FIPS re-self-test succeeded: all algorithms verified and available.");
pr_info("wolfCrypt FIPS re-self-test succeeded: all algorithms verified and available.\n");
return count;
}
+3 -7
View File
@@ -10176,12 +10176,8 @@ void ge_tobytes(unsigned char *s,const ge_p2 *h)
s[31] ^= (unsigned char)((unsigned char)fe_isnegative(x) << 7);
}
#ifdef HAVE_ED25519_VERIFY
#ifndef CURVED25519_ASM_64BIT
#define fe_invert_nct fe_invert
#endif
/* ge tobytes */
#if defined(HAVE_ED25519_VERIFY) && defined(CURVED25519_ASM_64BIT)
/* ge tobytes_nct */
void ge_tobytes_nct(unsigned char *s,const ge_p2 *h)
{
ge recip;
@@ -10194,7 +10190,7 @@ void ge_tobytes_nct(unsigned char *s,const ge_p2 *h)
fe_tobytes(s,y);
s[31] ^= (unsigned char)((unsigned char)fe_isnegative(x) << 7);
}
#endif
#endif /* HAVE_ED25519_VERIFY && CURVED25519_ASM_64BIT */
#endif /* !ED25519_SMALL */
+6 -4
View File
@@ -2418,10 +2418,12 @@ static int wc_lms_treehash_update(LmsState* state, LmsPrivState* privState,
}
}
if (!useRoot && (ret == 0)) {
/* Copy stack back. */
XMEMCPY(stackCache->stack, stack, params->height * params->hash_len);
stackCache->offset = (word32)((size_t)sp - (size_t)stack);
if (ret == 0) {
if (!useRoot) {
/* Copy stack back. */
XMEMCPY(stackCache->stack, stack, params->height * params->hash_len);
stackCache->offset = (word32)((size_t)sp - (size_t)stack);
}
}
WC_FREE_VAR_EX(stack, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+3 -1
View File
@@ -85,11 +85,13 @@ WOLFSSL_LOCAL void sc_reduce(byte* s);
WOLFSSL_LOCAL void sc_muladd(byte* s, const byte* a, const byte* b,
const byte* c);
WOLFSSL_LOCAL void ge_tobytes(unsigned char *s,const ge_p2 *h);
#ifndef ED25519_SMALL
#ifdef HAVE_ED25519_VERIFY
#if !defined(ED25519_SMALL) && defined(CURVED25519_ASM_64BIT)
WOLFSSL_LOCAL void ge_tobytes_nct(unsigned char *s,const ge_p2 *h);
#else
#define ge_tobytes_nct ge_tobytes
#endif
#endif /* HAVE_ED25519_VERIFY */
#ifndef GE_P3_TOBYTES_IMPL
#define ge_p3_tobytes(s, h) ge_tobytes((s), (const ge_p2 *)(h))
#else