I tracked this down to structure padding, which is weird on ARM. The EINVAL comes from: if ((data_len % DB_AES_CHUNK) != 0) return (EINVAL); in __aes_encrypt(), called by __db_encrypt_and_checksum_pg().
data_len is calculated as DBMETASIZE - P_OVERHEAD(dbp). For an encrypted database this evaluates to 448, a multiple of DB_AES_CHUNK = 16. On ARM (old ABI) it evaluates to 446 because sizeof(PG_CRYPTO) is 40 and not 38 as expected. So encrypted databases never worked on this architecture, and we should be able to fix this up by replacing sizeof(PG_CRYPTO) with SIZEOF_PG_CRYPTO defined to 38. A similar hack is already used for sizeof(PAGE). Not yet tested on ARM, as it takes about 4 hours to run the test suite on agnesi. Will report the results when that's done. Ben. --- db-4.7.25.orig/dbinc/db_page.h +++ db-4.7.25/dbinc/db_page.h @@ -223,6 +223,17 @@ */ } PG_CRYPTO; +/* + * With most compilers sizeof(PG_CRYPTO) == 38. However some ABIs + * require it to be padded to 40 bytes. The padding must be excluded + * from our size calculations due to the 16-byte alignment requirement + * for crypto. + * + * A similar problem applies to PG_CHKSUM, but it's too late to change + * that. + */ +#define SIZEOF_PG_CRYPTO 38 + typedef struct _db_page { DB_LSN lsn; /* 00-07: Log sequence number. */ db_pgno_t pgno; /* 08-11: Current page number. */ @@ -258,7 +269,7 @@ */ #define P_INP(dbp, pg) \ ((db_indx_t *)((u_int8_t *)(pg) + SIZEOF_PAGE + \ - (F_ISSET((dbp), DB_AM_ENCRYPT) ? sizeof(PG_CRYPTO) : \ + (F_ISSET((dbp), DB_AM_ENCRYPT) ? SIZEOF_PG_CRYPTO : \ (F_ISSET((dbp), DB_AM_CHKSUM) ? sizeof(PG_CHKSUM) : 0)))) #define P_IV(dbp, pg) \
signature.asc
Description: This is a digitally signed message part