diff --git a/kernel/cipher/Kbuild b/kernel/cipher/Kbuild index 6471fbf..5ac8909 100644 --- a/kernel/cipher/Kbuild +++ b/kernel/cipher/Kbuild @@ -20,9 +20,39 @@ # trees are not built here. # # WHAT IT IS FOR. AES-128-CTR at SRTP packet sizes, where a userspace streamer -# would otherwise do it on the CPU, plus a TRNG and an RSA block that nothing -# uses yet. Read the next paragraph before assuming the first of those is a -# win. +# would otherwise do it on the CPU, the key ladder the recorder's chip-bound +# mode wraps clip keys with, and a TRNG. Read the next paragraph before +# assuming the first of those is a win. +# +# WHAT IS NOT BUILT, and why the object list below is shorter than the vendor's +# build.mak. The SDK tree is a whole crypto stack, and a kernel module gets no +# dead-code elimination: `ld -r` takes every object named here, reachable or +# not, so an unused subsystem is not free, it is shipped. Two of them were, +# and together they were half the module -- 39 KB of RSA (the IFEP hardware +# driver plus a software mbedTLS bignum/RSA/ASN.1 fallback compiled into the +# kernel) and 14 KB of hash (SHA-1 through SHA-512, HMAC, SM3). Neither has a +# caller: majestic is the only thing that opens /dev/cipher on these boards and +# it uses symc, klad and the TRNG -- its cipher_abi.h says why not the other +# two, the engine's HMAC-SHA1 being five times slower than mbedTLS and its RSA +# being a once-per-clip operation userspace already does. Also gone are the +# _v100 cores and the ext_* extensions, which this part's CHIP_TYPE compiles +# down to empty objects -- no bytes, but no reason to name them either. +# +# Measured, same toolchain and kernel, gk7205v200: open_cipher.ko as installed +# (INSTALL_MOD_STRIP=1) goes from 172,328 to 96,188 bytes, -44.2%, and about +# 23 KB off an xz squashfs rootfs. For scale, gk7205v300_lite failed CI on +# 2026-09-06 four kilobytes over its 5120 KB partition. +# +# The vendor sources stay in the tree untouched; drivers/kapi_hash_rsa_absent.c +# supplies the twelve entry points kapi_dispatch.c needs, and only those twelve +# -- nothing else in the module reaches into either subsystem. Restoring one is +# putting its objects back on this list and taking that file off, not a merge. +# hi3516cv500 is trimmed the same way from its own kbuild, with its own copy of +# that file: the two trees are different SDK vintages and the kapi signatures +# differ, so the boundary was re-checked there rather than assumed from here. +# The other chips that name cipher objects build no cipher module (av100, +# cv200, cv100) or build a different, small driver (hi3520dv200's V2-era +# hi_cipher, hi3519dv500's V5 security_subsys) with none of this weight. # # WHAT IT IS WORTH DEPENDS ON HOW IT IS DRIVEN, and this file used to claim # more than the evidence carried. Per 1100-byte packet the engine costs half @@ -76,35 +106,15 @@ EV200_CIPHER = cipher/hi3516ev200/src $(PREFIX)cipher-objs := \ $(EV200_CIPHER)/drv/cipher_initdevice.o \ - $(EV200_CIPHER)/drv/cipher_v1.0/drivers/core/drv_symc_v100.o \ $(EV200_CIPHER)/drv/cipher_v1.0/drivers/core/drv_symc_v200.o \ - $(EV200_CIPHER)/drv/cipher_v1.0/drivers/core/drv_hash_v100.o \ - $(EV200_CIPHER)/drv/cipher_v1.0/drivers/core/drv_hash_v200.o \ - $(EV200_CIPHER)/drv/cipher_v1.0/drivers/core/drv_ifep_rsa_v100.o \ - $(EV200_CIPHER)/drv/cipher_v1.0/drivers/core/drv_trng_v100.o \ $(EV200_CIPHER)/drv/cipher_v1.0/drivers/core/drv_trng_v200.o \ $(EV200_CIPHER)/drv/cipher_v1.0/drivers/core/drv_lib.o \ $(EV200_CIPHER)/drv/cipher_v1.0/drivers/crypto/cryp_symc.o \ - $(EV200_CIPHER)/drv/cipher_v1.0/drivers/crypto/cryp_hash.o \ $(EV200_CIPHER)/drv/cipher_v1.0/drivers/crypto/cryp_trng.o \ - $(EV200_CIPHER)/drv/cipher_v1.0/drivers/crypto/cryp_rsa.o \ $(EV200_CIPHER)/drv/cipher_v1.0/drivers/kapi_symc.o \ - $(EV200_CIPHER)/drv/cipher_v1.0/drivers/kapi_hash.o \ - $(EV200_CIPHER)/drv/cipher_v1.0/drivers/kapi_rsa.o \ $(EV200_CIPHER)/drv/cipher_v1.0/drivers/kapi_trng.o \ $(EV200_CIPHER)/drv/cipher_v1.0/drivers/kapi_dispatch.o \ - $(EV200_CIPHER)/drv/cipher_v1.0/drivers/extend/mbedtls/bignum.o \ - $(EV200_CIPHER)/drv/cipher_v1.0/drivers/extend/mbedtls/md.o \ - $(EV200_CIPHER)/drv/cipher_v1.0/drivers/extend/mbedtls/rsa.o \ - $(EV200_CIPHER)/drv/cipher_v1.0/drivers/extend/mbedtls/asn1parse.o \ - $(EV200_CIPHER)/drv/cipher_v1.0/drivers/extend/mbedtls/oid.o \ - $(EV200_CIPHER)/drv/cipher_v1.0/drivers/extend/mbedtls/platform_util.o \ - $(EV200_CIPHER)/drv/cipher_v1.0/drivers/extend/mbedtls/rsa_internal.o \ - $(EV200_CIPHER)/drv/cipher_v1.0/drivers/extend/ext_aead.o \ - $(EV200_CIPHER)/drv/cipher_v1.0/drivers/extend/ext_hash.o \ - $(EV200_CIPHER)/drv/cipher_v1.0/drivers/extend/ext_symc.o \ - $(EV200_CIPHER)/drv/cipher_v1.0/drivers/extend/ext_sm3.o \ - $(EV200_CIPHER)/drv/cipher_v1.0/drivers/extend/ext_sm4.o \ + $(EV200_CIPHER)/drv/cipher_v1.0/drivers/kapi_hash_rsa_absent.o \ $(EV200_CIPHER)/drv/cipher_v1.0/osal/drv_osal_init_linux.o \ $(EV200_CIPHER)/drv/cipher_v1.0/osal/drv_osal_sys_linux.o \ $(EV200_CIPHER)/drv/cipher_v1.0/compat/hi_drv_compat.o \ diff --git a/kernel/cipher/hi3516cv500/src/drv/cipher_v1.0/drivers/kapi_hash_rsa_absent.c b/kernel/cipher/hi3516cv500/src/drv/cipher_v1.0/drivers/kapi_hash_rsa_absent.c new file mode 100644 index 0000000..ff591b0 --- /dev/null +++ b/kernel/cipher/hi3516cv500/src/drv/cipher_v1.0/drivers/kapi_hash_rsa_absent.c @@ -0,0 +1,139 @@ +/* + * The hash and RSA halves of the Cipher driver, absent. + * + * The hi3516cv500 counterpart of the same file in the hi3516ev200 tree, and + * it is a separate file rather than a shared one because these two trees are + * different SDK vintages: cv500's kapi_rsa_* take a cryp_rsa_crypt_data, its + * kapi_hash_finish takes the output buffer's length, and its log macros are + * lower case. Read kernel/cipher/Kbuild for why the trim exists at all -- the + * short of it is that a kernel module gets no dead-code elimination, so the + * vendor SDK's whole crypto stack shipped whether or not anything reached it, + * and RSA plus hash were about half of open_cipher.ko. + * + * Nothing calls them. majestic is the only consumer of /dev/cipher on these + * boards -- it goes straight to the ioctls, see its + * include/majestic/hisi/cipher_abi.h -- and it uses the symmetric channel, the + * key ladder and the TRNG. Not the hash, whose handle closes on finish so the + * key is reprogrammed per packet, measured five times slower than mbedTLS. Not + * RSA, which the recorder needs once per clip and userspace mbedTLS already + * does. `nm` over this tree's own objects agrees with the ev200 one: the two + * subsystems are reached through exactly the twelve symbols below, all of them + * from kapi_dispatch.c, and nothing in symc, klad, the TRNG or the OTP path + * touches them. + * + * init/deinit/release succeed, because crypto_entry() aborts the module load + * on anything else and the symmetric path has no business failing over an + * absent hash. Every real operation returns HI_ERR_CIPHER_UNSUPPORTED. + * + * THE DISPATCH TABLE IS UNTOUCHED, which is the point of stubbing here rather + * than editing kapi_dispatch.c: crypto_ioctl() indexes g_dispatch_func[] by + * the command's nr and then checks the row's cmd matches, and majestic derives + * its command numbers from the same struct sizes the driver does, so a removed + * row would land every later command on the wrong handler. + * + * The vendor sources stay in the tree untouched. Restoring either subsystem is + * putting its objects back on hi3516cv500.kbuild's list and dropping this file + * from it -- not a merge. + */ + +#include "drv_osal_lib.h" +#include "cryp_rsa.h" + +/* Spelled out rather than borrowed: this tree defines no CRYPTO_UNUSED. */ +#define UNUSED(x) ((void)(x)) + +/* ---- hash: SHA-1/224/256/384/512, HMAC, SM3 ---- */ + +hi_s32 kapi_hash_init(hi_void) +{ + return HI_SUCCESS; +} + +hi_s32 kapi_hash_deinit(hi_void) +{ + return HI_SUCCESS; +} + +hi_s32 kapi_hash_release(hi_void) +{ + return HI_SUCCESS; +} + +hi_s32 kapi_hash_start(hi_u32 *id, hi_cipher_hash_type type, + hi_u8 *key, hi_u32 keylen) +{ + UNUSED(id); + UNUSED(type); + UNUSED(key); + UNUSED(keylen); + + hi_log_error("error, hash is not built into this module\n"); + return HI_ERR_CIPHER_UNSUPPORTED; +} + +hi_s32 kapi_hash_update(hi_u32 id, hi_u8 *input, hi_u32 length, + hash_chunk_src src) +{ + UNUSED(id); + UNUSED(input); + UNUSED(length); + UNUSED(src); + + return HI_ERR_CIPHER_UNSUPPORTED; +} + +hi_s32 kapi_hash_finish(hi_u32 id, hi_u8 *hash, hi_u32 hash_buf_len, + hi_u32 *hashlen) +{ + UNUSED(id); + UNUSED(hash); + UNUSED(hash_buf_len); + UNUSED(hashlen); + + return HI_ERR_CIPHER_UNSUPPORTED; +} + +/* ---- RSA: the IFEP engine and the mbedTLS software fallback ---- */ + +hi_s32 kapi_rsa_init(hi_void) +{ + return HI_SUCCESS; +} + +hi_s32 kapi_rsa_deinit(hi_void) +{ + return HI_SUCCESS; +} + +hi_s32 kapi_rsa_encrypt(cryp_rsa_key *key, cryp_rsa_crypt_data *rsa) +{ + UNUSED(key); + UNUSED(rsa); + + hi_log_error("error, rsa is not built into this module\n"); + return HI_ERR_CIPHER_UNSUPPORTED; +} + +hi_s32 kapi_rsa_decrypt(cryp_rsa_key *key, cryp_rsa_crypt_data *rsa) +{ + UNUSED(key); + UNUSED(rsa); + + return HI_ERR_CIPHER_UNSUPPORTED; +} + +hi_s32 kapi_rsa_sign_hash(cryp_rsa_key *key, cryp_rsa_sign_data *rsa) +{ + UNUSED(key); + UNUSED(rsa); + + return HI_ERR_CIPHER_UNSUPPORTED; +} + +hi_s32 kapi_rsa_verify_hash(cryp_rsa_key *key, cryp_rsa_sign_data *rsa) +{ + UNUSED(key); + UNUSED(rsa); + + return HI_ERR_CIPHER_UNSUPPORTED; +} diff --git a/kernel/cipher/hi3516ev200/src/drv/cipher_v1.0/drivers/kapi_hash_rsa_absent.c b/kernel/cipher/hi3516ev200/src/drv/cipher_v1.0/drivers/kapi_hash_rsa_absent.c new file mode 100644 index 0000000..e308af6 --- /dev/null +++ b/kernel/cipher/hi3516ev200/src/drv/cipher_v1.0/drivers/kapi_hash_rsa_absent.c @@ -0,0 +1,166 @@ +/* + * The hash and RSA halves of the Cipher driver, absent. + * + * WHY. The vendor tree is a whole crypto stack, and a kernel module is linked + * with `ld -r`: every object named in the Kbuild ships, reachable or not, + * because there is no --gc-sections and nothing to prune a .ko. Of the + * 110 KB of code and data in open_cipher.ko, 39 KB was RSA -- the IFEP + * hardware driver plus a whole software mbedTLS bignum/RSA/ASN.1 fallback + * compiled into the kernel -- and 14 KB was the hash engine, SHA-1 through + * SHA-512 with HMAC. Half the module, for two subsystems no OpenIPC + * userspace calls. + * + * Nothing calls them, and that is measured rather than assumed. majestic is + * the only consumer of /dev/cipher on these boards -- it talks to the ioctls + * directly, see its include/majestic/hisi/cipher_abi.h -- and it uses the + * symmetric channel, the key ladder and the TRNG. Not the hash: the engine's + * HMAC-SHA1 closes its handle on finish and so reprograms the key for every + * packet, which measured 192.4 us against mbedTLS's 37.4, five times worse. + * Not RSA either: the recorder's public-key mode wraps a clip key once per + * clip, and mbedTLS does that in userspace. + * + * WHAT THIS FILE IS. The twelve entry points those two subsystems export to + * kapi_dispatch.c, and the only twelve -- `nm` says nothing else in the + * module reaches into them. init/deinit/release succeed, because + * crypto_entry() aborts the whole module load on anything else and the + * symmetric path has no business failing over an absent hash. Every actual + * operation returns HI_ERR_CIPHER_UNSUPPORTED, which is what a caller of + * HI_UNF_CIPHER_HashInit() would have to handle anyway on a part whose + * engine is missing. + * + * THE DISPATCH TABLE IS UNTOUCHED, and that is the point of stubbing here + * rather than editing kapi_dispatch.c. crypto_ioctl() indexes dispatch_func[] + * by the command's nr and then checks the row's cmd matches, so removing the + * hash and RSA rows would shift every command after them onto the wrong + * handler -- and majestic derives its command numbers from the same struct + * sizes the driver does. The rows stay, the handlers stay, and what changes + * is only what they call. + * + * The vendor sources are still in the tree, unmodified. Restoring either + * subsystem is putting its objects back in the Kbuild and dropping this file + * from the list -- not a merge. + */ + +#include "drv_osal_lib.h" +#include "cryp_rsa.h" + +/* Spelled out rather than borrowed from drv_cipher_kapi.h's CRYPTO_UNUSED, + * which is ((x) = (x)) and so needs a modifiable lvalue -- and which the + * hi3516cv500 tree, where this file would go next, does not define. */ +#define UNUSED(x) ((void)(x)) + +/* ---- hash: SHA-1/224/256/384/512, HMAC, SM3 ---- */ + +hi_s32 kapi_hash_init(hi_void) +{ + return HI_SUCCESS; +} + +hi_s32 kapi_hash_deinit(hi_void) +{ + return HI_SUCCESS; +} + +hi_s32 kapi_hash_release(hi_void) +{ + return HI_SUCCESS; +} + +hi_s32 kapi_hash_start(hi_u32 *id, hi_cipher_hash_type type, + hi_u8 *key, hi_u32 keylen) +{ + UNUSED(id); + UNUSED(type); + UNUSED(key); + UNUSED(keylen); + + HI_LOG_ERROR("error, hash is not built into this module\n"); + return HI_ERR_CIPHER_UNSUPPORTED; +} + +hi_s32 kapi_hash_update(hi_u32 id, hi_u8 *input, hi_u32 length, + hash_chunk_src src) +{ + UNUSED(id); + UNUSED(input); + UNUSED(length); + UNUSED(src); + + return HI_ERR_CIPHER_UNSUPPORTED; +} + +hi_s32 kapi_hash_finish(hi_u32 id, hi_u8 *hash, hi_u32 *hashlen) +{ + UNUSED(id); + UNUSED(hash); + UNUSED(hashlen); + + return HI_ERR_CIPHER_UNSUPPORTED; +} + +/* ---- RSA: the IFEP engine and the mbedTLS software fallback ---- */ + +hi_s32 kapi_rsa_init(hi_void) +{ + return HI_SUCCESS; +} + +hi_s32 kapi_rsa_deinit(hi_void) +{ + return HI_SUCCESS; +} + +hi_s32 kapi_rsa_encrypt(cryp_rsa_key *key, hi_cipher_rsa_enc_scheme scheme, + hi_u8 *in, hi_u32 inlen, hi_u8 *out, hi_u32 *outlen) +{ + UNUSED(key); + UNUSED(scheme); + UNUSED(in); + UNUSED(inlen); + UNUSED(out); + UNUSED(outlen); + + HI_LOG_ERROR("error, rsa is not built into this module\n"); + return HI_ERR_CIPHER_UNSUPPORTED; +} + +hi_s32 kapi_rsa_decrypt(cryp_rsa_key *key, hi_cipher_rsa_enc_scheme scheme, + hi_u8 *in, hi_u32 inlen, hi_u8 *out, hi_u32 *outlen) +{ + UNUSED(key); + UNUSED(scheme); + UNUSED(in); + UNUSED(inlen); + UNUSED(out); + UNUSED(outlen); + + return HI_ERR_CIPHER_UNSUPPORTED; +} + +hi_s32 kapi_rsa_sign_hash(cryp_rsa_key *key, hi_cipher_rsa_sign_scheme scheme, + hi_u8 *hash, hi_u32 hlen, + hi_u8 *sign, hi_u32 *signlen) +{ + UNUSED(key); + UNUSED(scheme); + UNUSED(hash); + UNUSED(hlen); + UNUSED(sign); + UNUSED(signlen); + + return HI_ERR_CIPHER_UNSUPPORTED; +} + +hi_s32 kapi_rsa_verify_hash(cryp_rsa_key *key, hi_cipher_rsa_sign_scheme scheme, + hi_u8 *hash, hi_u32 hlen, + hi_u8 *sign, hi_u32 signlen) +{ + UNUSED(key); + UNUSED(scheme); + UNUSED(hash); + UNUSED(hlen); + UNUSED(sign); + UNUSED(signlen); + + return HI_ERR_CIPHER_UNSUPPORTED; +} diff --git a/kernel/hi3516cv500.kbuild b/kernel/hi3516cv500.kbuild index e06e546..2782189 100644 --- a/kernel/hi3516cv500.kbuild +++ b/kernel/hi3516cv500.kbuild @@ -214,38 +214,33 @@ obj-m += $(PREFIX)ir.o #obj-m += $(PREFIX)hi_user.o # --- Cipher module (source driver) --- +# +# The object list is shorter than the vendor's build.mak, and the reasoning is +# in kernel/cipher/Kbuild, which does the same for the hi3516ev200 tree: a +# kernel module gets no dead-code elimination, so every object named here +# ships whether or not an ioctl reaches it, and the hash and RSA subsystems +# were about half of open_cipher.ko for no caller. majestic is the only thing +# that opens /dev/cipher and it uses symc, klad and the TRNG. Verified against +# this tree's own objects rather than assumed from the other one: the two +# subsystems are reached through exactly twelve symbols, all of them from +# kapi_dispatch.c, which drivers/kapi_hash_rsa_absent.c now supplies. +# +# Measured on hi3516cv500, same toolchain and kernel: open_cipher.ko as +# installed goes from 171,380 to 97,208 bytes, -43.3%, and 52,468 to 29,476 +# compressed. Restoring a subsystem is putting its objects back on this list +# and taking that file off, not a merge; the vendor sources are untouched. CV500_CIPHER = cipher/hi3516cv500/src $(PREFIX)cipher-objs := \ $(CV500_CIPHER)/drv/cipher_initdevice.o \ - $(CV500_CIPHER)/drv/cipher_v1.0/drivers/core/drv_symc_v100.o \ $(CV500_CIPHER)/drv/cipher_v1.0/drivers/core/drv_symc_v200.o \ - $(CV500_CIPHER)/drv/cipher_v1.0/drivers/core/drv_hash_v100.o \ - $(CV500_CIPHER)/drv/cipher_v1.0/drivers/core/drv_hash_v200.o \ - $(CV500_CIPHER)/drv/cipher_v1.0/drivers/core/drv_ifep_rsa_v100.o \ - $(CV500_CIPHER)/drv/cipher_v1.0/drivers/core/drv_trng_v100.o \ $(CV500_CIPHER)/drv/cipher_v1.0/drivers/core/drv_trng_v200.o \ $(CV500_CIPHER)/drv/cipher_v1.0/drivers/core/drv_lib.o \ $(CV500_CIPHER)/drv/cipher_v1.0/drivers/crypto/cryp_symc.o \ - $(CV500_CIPHER)/drv/cipher_v1.0/drivers/crypto/cryp_hash.o \ $(CV500_CIPHER)/drv/cipher_v1.0/drivers/crypto/cryp_trng.o \ - $(CV500_CIPHER)/drv/cipher_v1.0/drivers/crypto/cryp_rsa.o \ $(CV500_CIPHER)/drv/cipher_v1.0/drivers/kapi_symc.o \ - $(CV500_CIPHER)/drv/cipher_v1.0/drivers/kapi_hash.o \ - $(CV500_CIPHER)/drv/cipher_v1.0/drivers/kapi_rsa.o \ $(CV500_CIPHER)/drv/cipher_v1.0/drivers/kapi_trng.o \ $(CV500_CIPHER)/drv/cipher_v1.0/drivers/kapi_dispatch.o \ - $(CV500_CIPHER)/drv/cipher_v1.0/drivers/extend/mbedtls/bignum.o \ - $(CV500_CIPHER)/drv/cipher_v1.0/drivers/extend/mbedtls/md.o \ - $(CV500_CIPHER)/drv/cipher_v1.0/drivers/extend/mbedtls/rsa.o \ - $(CV500_CIPHER)/drv/cipher_v1.0/drivers/extend/mbedtls/asn1parse.o \ - $(CV500_CIPHER)/drv/cipher_v1.0/drivers/extend/mbedtls/oid.o \ - $(CV500_CIPHER)/drv/cipher_v1.0/drivers/extend/mbedtls/platform_util.o \ - $(CV500_CIPHER)/drv/cipher_v1.0/drivers/extend/mbedtls/rsa_internal.o \ - $(CV500_CIPHER)/drv/cipher_v1.0/drivers/extend/ext_aead.o \ - $(CV500_CIPHER)/drv/cipher_v1.0/drivers/extend/ext_hash.o \ - $(CV500_CIPHER)/drv/cipher_v1.0/drivers/extend/ext_symc.o \ - $(CV500_CIPHER)/drv/cipher_v1.0/drivers/extend/ext_sm3.o \ - $(CV500_CIPHER)/drv/cipher_v1.0/drivers/extend/ext_sm4.o \ + $(CV500_CIPHER)/drv/cipher_v1.0/drivers/kapi_hash_rsa_absent.o \ $(CV500_CIPHER)/drv/cipher_v1.0/osal/drv_osal_init_linux.o \ $(CV500_CIPHER)/drv/cipher_v1.0/osal/drv_osal_sys_linux.o \ $(CV500_CIPHER)/drv/cipher_v1.0/compat/hi_drv_compat.o \