diff options
| author | Ron Yorston <rmy@pobox.com> | 2025-06-09 13:23:49 +0100 |
|---|---|---|
| committer | Ron Yorston <rmy@pobox.com> | 2025-06-09 13:23:49 +0100 |
| commit | 596c443112d09506c3bf13ac98046a84b912e56c (patch) | |
| tree | 896fd4d7e43a71a8a15dbcec17f6cafcbe622635 /libbb | |
| parent | 854c647da7a84cf2aaa2c9a84ff1ca353bdaf9cf (diff) | |
| download | busybox-w32-cng_backend.tar.gz busybox-w32-cng_backend.tar.bz2 busybox-w32-cng_backend.zip | |
Use Windows library for cryptographic checksumscng_backend
Add a new feature to libbb, FEATURE_USE_CNG_API, which enables the
use of the Cryptography API: Next Generation library to calculate
checksums. It is disabled by default except in the mingw64u default
config, as the API requires Windows 10+ to function. Usage of this
API provides a size benefit and delegates hardware optimizations to
the operating system cryptography library.
Based on GitHub PR #498 by rfl890.
Saves 4064 bytes in the mingw64u case.
Diffstat (limited to '')
| -rw-r--r-- | libbb/Config.src | 10 | ||||
| -rw-r--r-- | libbb/hash_md5_sha.c | 86 |
2 files changed, 96 insertions, 0 deletions
diff --git a/libbb/Config.src b/libbb/Config.src index 61b4601d6..ed6521c33 100644 --- a/libbb/Config.src +++ b/libbb/Config.src | |||
| @@ -37,6 +37,14 @@ config PASSWORD_MINLEN | |||
| 37 | help | 37 | help |
| 38 | Minimum allowable password length. | 38 | Minimum allowable password length. |
| 39 | 39 | ||
| 40 | config FEATURE_USE_CNG_API | ||
| 41 | bool "Use the Windows CNG API for checksums (Windows 10+ only)" | ||
| 42 | default n | ||
| 43 | depends on PLATFORM_MINGW32 | ||
| 44 | help | ||
| 45 | Use the in-built Windows CNG API for checksums. | ||
| 46 | This reduces code size, but is only supported on Windows 10+. | ||
| 47 | |||
| 40 | config MD5_SMALL | 48 | config MD5_SMALL |
| 41 | int "MD5: Trade bytes for speed (0:fast, 3:slow)" | 49 | int "MD5: Trade bytes for speed (0:fast, 3:slow)" |
| 42 | default 1 # all "fast or small" options default to small | 50 | default 1 # all "fast or small" options default to small |
| @@ -67,6 +75,7 @@ config SHA1_SMALL | |||
| 67 | config SHA1_HWACCEL | 75 | config SHA1_HWACCEL |
| 68 | bool "SHA1: Use hardware accelerated instructions if possible" | 76 | bool "SHA1: Use hardware accelerated instructions if possible" |
| 69 | default y | 77 | default y |
| 78 | depends on !FEATURE_USE_CNG_API | ||
| 70 | help | 79 | help |
| 71 | On x86, this adds ~590 bytes of code. Throughput | 80 | On x86, this adds ~590 bytes of code. Throughput |
| 72 | is about twice as fast as fully-unrolled generic code. | 81 | is about twice as fast as fully-unrolled generic code. |
| @@ -74,6 +83,7 @@ config SHA1_HWACCEL | |||
| 74 | config SHA256_HWACCEL | 83 | config SHA256_HWACCEL |
| 75 | bool "SHA256: Use hardware accelerated instructions if possible" | 84 | bool "SHA256: Use hardware accelerated instructions if possible" |
| 76 | default y | 85 | default y |
| 86 | depends on !FEATURE_USE_CNG_API | ||
| 77 | help | 87 | help |
| 78 | On x86, this adds ~1k bytes of code. | 88 | On x86, this adds ~1k bytes of code. |
| 79 | 89 | ||
diff --git a/libbb/hash_md5_sha.c b/libbb/hash_md5_sha.c index 75a61c32c..abdacf939 100644 --- a/libbb/hash_md5_sha.c +++ b/libbb/hash_md5_sha.c | |||
| @@ -13,6 +13,90 @@ | |||
| 13 | 13 | ||
| 14 | #define NEED_SHA512 (ENABLE_SHA512SUM || ENABLE_USE_BB_CRYPT_SHA) | 14 | #define NEED_SHA512 (ENABLE_SHA512SUM || ENABLE_USE_BB_CRYPT_SHA) |
| 15 | 15 | ||
| 16 | #if ENABLE_FEATURE_USE_CNG_API | ||
| 17 | # include <windows.h> | ||
| 18 | # include <bcrypt.h> | ||
| 19 | |||
| 20 | // these work on Windows >= 10 | ||
| 21 | # define BCRYPT_MD5_ALG_HANDLE ((BCRYPT_ALG_HANDLE) 0x00000021) | ||
| 22 | # define BCRYPT_SHA1_ALG_HANDLE ((BCRYPT_ALG_HANDLE) 0x00000031) | ||
| 23 | # define BCRYPT_SHA256_ALG_HANDLE ((BCRYPT_ALG_HANDLE) 0x00000041) | ||
| 24 | # define BCRYPT_SHA512_ALG_HANDLE ((BCRYPT_ALG_HANDLE) 0x00000061) | ||
| 25 | |||
| 26 | # define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0) | ||
| 27 | |||
| 28 | static void die_if_error(NTSTATUS status, const char *function_name) { | ||
| 29 | if (!NT_SUCCESS(status)) { | ||
| 30 | bb_error_msg_and_die("call to %s failed: 0x%08lX", | ||
| 31 | function_name, (unsigned long)status); | ||
| 32 | } | ||
| 33 | } | ||
| 34 | |||
| 35 | /* Initialize structure containing state of computation. | ||
| 36 | * (RFC 1321, 3.3: Step 3) | ||
| 37 | */ | ||
| 38 | |||
| 39 | static void generic_init(struct bcrypt_hash_ctx_t *ctx, BCRYPT_ALG_HANDLE *alg_handle) { | ||
| 40 | DWORD hash_object_length = 0; | ||
| 41 | ULONG _unused; | ||
| 42 | NTSTATUS status; | ||
| 43 | |||
| 44 | status = BCryptGetProperty(alg_handle, BCRYPT_OBJECT_LENGTH, (PUCHAR)&hash_object_length, sizeof(DWORD), &_unused, 0); | ||
| 45 | die_if_error(status, "BCryptGetProperty"); | ||
| 46 | status = BCryptGetProperty(alg_handle, BCRYPT_HASH_LENGTH, (PUCHAR)&ctx->output_size, sizeof(DWORD), &_unused, 0); | ||
| 47 | die_if_error(status, "BCryptGetProperty"); | ||
| 48 | |||
| 49 | |||
| 50 | ctx->hash_obj = xmalloc(hash_object_length); | ||
| 51 | |||
| 52 | status = BCryptCreateHash(alg_handle, &ctx->handle, ctx->hash_obj, hash_object_length, NULL, 0, 0); | ||
| 53 | die_if_error(status, "BCryptCreateHash"); | ||
| 54 | } | ||
| 55 | |||
| 56 | void FAST_FUNC md5_begin(md5_ctx_t *ctx) | ||
| 57 | { | ||
| 58 | generic_init(ctx, BCRYPT_MD5_ALG_HANDLE); | ||
| 59 | } | ||
| 60 | |||
| 61 | void FAST_FUNC sha1_begin(sha1_ctx_t *ctx) | ||
| 62 | { | ||
| 63 | generic_init(ctx, BCRYPT_SHA1_ALG_HANDLE); | ||
| 64 | } | ||
| 65 | |||
| 66 | /* Initialize structure containing state of computation. | ||
| 67 | (FIPS 180-2:5.3.2) */ | ||
| 68 | void FAST_FUNC sha256_begin(sha256_ctx_t *ctx) | ||
| 69 | { | ||
| 70 | generic_init(ctx, BCRYPT_SHA256_ALG_HANDLE); | ||
| 71 | } | ||
| 72 | |||
| 73 | #if NEED_SHA512 | ||
| 74 | /* Initialize structure containing state of computation. | ||
| 75 | (FIPS 180-2:5.3.3) */ | ||
| 76 | void FAST_FUNC sha512_begin(sha512_ctx_t *ctx) | ||
| 77 | { | ||
| 78 | generic_init(ctx, BCRYPT_SHA512_ALG_HANDLE); | ||
| 79 | } | ||
| 80 | #endif /* NEED_SHA512 */ | ||
| 81 | |||
| 82 | void FAST_FUNC generic_hash(struct bcrypt_hash_ctx_t *ctx, const void *buffer, size_t len) | ||
| 83 | { | ||
| 84 | /* | ||
| 85 | for perf, no error checking here | ||
| 86 | */ | ||
| 87 | /*NTSTATUS status = */ BCryptHashData(ctx->handle, (const PUCHAR)buffer, len, 0); | ||
| 88 | // die_if_error(status, "BCryptHashData"); | ||
| 89 | } | ||
| 90 | |||
| 91 | unsigned FAST_FUNC generic_end(struct bcrypt_hash_ctx_t *ctx, void *resbuf) | ||
| 92 | { | ||
| 93 | NTSTATUS status = BCryptFinishHash(ctx->handle, resbuf, ctx->output_size, 0); | ||
| 94 | die_if_error(status, "BCryptFinishHash"); | ||
| 95 | free(ctx->hash_obj); | ||
| 96 | return ctx->output_size; | ||
| 97 | } | ||
| 98 | #endif /* !ENABLE_FEATURE_USE_CNG_API */ | ||
| 99 | |||
| 16 | #if ENABLE_SHA1_HWACCEL || ENABLE_SHA256_HWACCEL | 100 | #if ENABLE_SHA1_HWACCEL || ENABLE_SHA256_HWACCEL |
| 17 | # if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) | 101 | # if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) |
| 18 | static void cpuid_eax_ebx_ecx(unsigned *eax, unsigned *ebx, unsigned *ecx, unsigned *edx) | 102 | static void cpuid_eax_ebx_ecx(unsigned *eax, unsigned *ebx, unsigned *ecx, unsigned *edx) |
| @@ -80,6 +164,7 @@ static ALWAYS_INLINE uint64_t rotl64(uint64_t x, unsigned n) | |||
| 80 | return (x << n) | (x >> (64 - n)); | 164 | return (x << n) | (x >> (64 - n)); |
| 81 | } | 165 | } |
| 82 | 166 | ||
| 167 | #if !ENABLE_FEATURE_USE_CNG_API | ||
| 83 | /* Process the remaining bytes in the buffer */ | 168 | /* Process the remaining bytes in the buffer */ |
| 84 | static void FAST_FUNC common64_end(md5_ctx_t *ctx, int swap_needed) | 169 | static void FAST_FUNC common64_end(md5_ctx_t *ctx, int swap_needed) |
| 85 | { | 170 | { |
| @@ -1367,6 +1452,7 @@ unsigned FAST_FUNC sha512_end(sha512_ctx_t *ctx, void *resbuf) | |||
| 1367 | return sizeof(ctx->hash); | 1452 | return sizeof(ctx->hash); |
| 1368 | } | 1453 | } |
| 1369 | #endif /* NEED_SHA512 */ | 1454 | #endif /* NEED_SHA512 */ |
| 1455 | #endif /* !ENABLE_FEATURE_USE_CNG_API */ | ||
| 1370 | 1456 | ||
| 1371 | 1457 | ||
| 1372 | /* | 1458 | /* |
