Index: lib/sanitizer_common/sanitizer_common_interceptors.inc =================================================================== --- lib/sanitizer_common/sanitizer_common_interceptors.inc +++ lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -8360,6 +8360,106 @@ #define INIT_MD2 #endif +#if SANITIZER_INTERCEPT_SHA2 +#define SHA2_INTERCEPTORS(LEN, SHA2_STATE_T) \ + INTERCEPTOR(void, SHA##LEN##_Init, void *context) { \ + void *ctx; \ + COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_Init, context); \ + REAL(SHA##LEN##_Init)(context); \ + if (context) \ + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, SHA##LEN##_CTX_sz); \ + } \ + INTERCEPTOR(void, SHA##LEN##_Update, void *context, \ + const u8 *data, SIZE_T len) { \ + void *ctx; \ + COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_Update, context, data, len); \ + if (data && len > 0) \ + COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); \ + if (context) \ + COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA##LEN##_CTX_sz); \ + REAL(SHA##LEN##_Update)(context, data, len); \ + if (context) \ + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, SHA##LEN##_CTX_sz); \ + } \ + INTERCEPTOR(void, SHA##LEN##_Final, u8 digest[SHA##LEN##_digest_length], \ + void *context) { \ + void *ctx; \ + COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_Final, digest, context); \ + if (context) \ + COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA##LEN##_CTX_sz); \ + REAL(SHA##LEN##_Final)(digest, context); \ + if (digest) \ + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, \ + sizeof(digest[0]) * \ + SHA##LEN##_digest_length); \ + } \ + INTERCEPTOR(char *, SHA##LEN##_End, void *context, char *buf) { \ + void *ctx; \ + COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_End, context, buf); \ + if (context) \ + COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA##LEN##_CTX_sz); \ + char *ret = REAL(SHA##LEN##_End)(context, buf); \ + if (ret) \ + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA##LEN##_return_length); \ + return ret; \ + } \ + INTERCEPTOR(char *, SHA##LEN##_File, const char *filename, char *buf) { \ + void *ctx; \ + COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_File, filename, buf); \ + if (filename) \ + COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1);\ + char *ret = REAL(SHA##LEN##_File)(filename, buf); \ + if (ret) \ + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA##LEN##_return_length); \ + return ret; \ + } \ + INTERCEPTOR(char *, SHA##LEN##_FileChunk, const char *filename, char *buf, \ + OFF_T offset, OFF_T length) { \ + void *ctx; \ + COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_FileChunk, filename, buf, offset, \ + length); \ + if (filename) \ + COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1);\ + char *ret = REAL(SHA##LEN##_FileChunk)(filename, buf, offset, length); \ + if (ret) \ + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA##LEN##_return_length); \ + return ret; \ + } \ + INTERCEPTOR(char *, SHA##LEN##_Data, u8 *data, SIZE_T len, char *buf) { \ + void *ctx; \ + COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_Data, data, len, buf); \ + if (data && len > 0) \ + COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); \ + char *ret = REAL(SHA##LEN##_Data)(data, len, buf); \ + if (ret) \ + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA##LEN##_return_length); \ + return ret; \ + } + +SHA2_INTERCEPTORS(224, u32); +SHA2_INTERCEPTORS(256, u32); +SHA2_INTERCEPTORS(384, u64); +SHA2_INTERCEPTORS(512, u64); + +#define INIT_SHA2_INTECEPTORS(LEN) \ + COMMON_INTERCEPT_FUNCTION(SHA##LEN##_Init); \ + COMMON_INTERCEPT_FUNCTION(SHA##LEN##_Update); \ + COMMON_INTERCEPT_FUNCTION(SHA##LEN##_Final); \ + COMMON_INTERCEPT_FUNCTION(SHA##LEN##_End); \ + COMMON_INTERCEPT_FUNCTION(SHA##LEN##_File); \ + COMMON_INTERCEPT_FUNCTION(SHA##LEN##_FileChunk); \ + COMMON_INTERCEPT_FUNCTION(SHA##LEN##_Data) + +#define INIT_SHA2 \ + INIT_SHA2_INTECEPTORS(224); \ + INIT_SHA2_INTECEPTORS(256); \ + INIT_SHA2_INTECEPTORS(384); \ + INIT_SHA2_INTECEPTORS(512) +#undef SHA2_INTERCEPTORS +#else +#define INIT_SHA2 +#endif + static void InitializeCommonInterceptors() { static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1]; interceptor_metadata_map = @@ -8636,6 +8736,7 @@ INIT_MD5; INIT_FSEEK; INIT_MD2; + INIT_SHA2; INIT___PRINTF_CHK; } Index: lib/sanitizer_common/sanitizer_platform_interceptors.h =================================================================== --- lib/sanitizer_common/sanitizer_platform_interceptors.h +++ lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -541,5 +541,6 @@ #define SANITIZER_INTERCEPT_MD5 SI_NETBSD #define SANITIZER_INTERCEPT_FSEEK SI_NETBSD #define SANITIZER_INTERCEPT_MD2 SI_NETBSD +#define SANITIZER_INTERCEPT_SHA2 SI_NETBSD #endif // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H Index: lib/sanitizer_common/sanitizer_platform_limits_netbsd.h =================================================================== --- lib/sanitizer_common/sanitizer_platform_limits_netbsd.h +++ lib/sanitizer_common/sanitizer_platform_limits_netbsd.h @@ -2237,6 +2237,19 @@ extern const unsigned MD5_return_length; extern const unsigned fpos_t_sz; + +#define SHA2_EXTERN(LEN) \ + extern const unsigned SHA##LEN##_CTX_sz; \ + extern const unsigned SHA##LEN##_return_length; \ + extern const unsigned SHA##LEN##_block_length; \ + extern const unsigned SHA##LEN##_digest_length + +SHA2_EXTERN(224); +SHA2_EXTERN(256); +SHA2_EXTERN(384); +SHA2_EXTERN(512); + +#undef SHA2_EXTERN } // namespace __sanitizer #define CHECK_TYPE_SIZE(TYPE) \ Index: lib/sanitizer_common/sanitizer_platform_limits_netbsd.cc =================================================================== --- lib/sanitizer_common/sanitizer_platform_limits_netbsd.cc +++ lib/sanitizer_common/sanitizer_platform_limits_netbsd.cc @@ -2115,6 +2115,19 @@ const unsigned MD5_return_length = MD5_DIGEST_STRING_LENGTH; const unsigned fpos_t_sz = sizeof(fpos_t); + +#define SHA2_CONST(LEN) \ + const unsigned SHA##LEN##_CTX_sz = sizeof(SHA##LEN##_CTX); \ + const unsigned SHA##LEN##_return_length = SHA##LEN##_DIGEST_STRING_LENGTH; \ + const unsigned SHA##LEN##_block_length = SHA##LEN##_BLOCK_LENGTH; \ + const unsigned SHA##LEN##_digest_length = SHA##LEN##_DIGEST_LENGTH + +SHA2_CONST(224); +SHA2_CONST(256); +SHA2_CONST(384); +SHA2_CONST(512); + +#undef SHA2_CONST } // namespace __sanitizer using namespace __sanitizer; Index: test/sanitizer_common/TestCases/NetBSD/sha2.cc =================================================================== --- test/sanitizer_common/TestCases/NetBSD/sha2.cc +++ test/sanitizer_common/TestCases/NetBSD/sha2.cc @@ -0,0 +1,206 @@ +// RUN: %clangxx -O0 -g %s -DSHASIZE=224 -o %t && %run %t 2>&1 | FileCheck %s -check-prefix=CHECK-224 +// RUN: %clangxx -O0 -g %s -DSHASIZE=256 -o %t && %run %t 2>&1 | FileCheck %s -check-prefix=CHECK-256 +// RUN: %clangxx -O0 -g %s -DSHASIZE=384 -o %t && %run %t 2>&1 | FileCheck %s -check-prefix=CHECK-384 +// RUN: %clangxx -O0 -g %s -DSHASIZE=512 -o %t && %run %t 2>&1 | FileCheck %s -check-prefix=CHECK-512 + +#include + +#include +#include +#include +#include +#include +#include + +#ifndef SHASIZE +#error SHASIZE must be defined +#endif + +#define _SHA_CTX(x) SHA##x##_CTX +#define SHA_CTX(x) _SHA_CTX(x) + +#define _SHA_DIGEST_LENGTH(x) SHA##x##_DIGEST_LENGTH +#define SHA_DIGEST_LENGTH(x) _SHA_DIGEST_LENGTH(x) + +#define _SHA_DIGEST_STRING_LENGTH(x) SHA##x##_DIGEST_STRING_LENGTH +#define SHA_DIGEST_STRING_LENGTH(x) _SHA_DIGEST_STRING_LENGTH(x) + +#define _SHA_Init(x) SHA##x##_Init +#define SHA_Init(x) _SHA_Init(x) + +#define _SHA_Update(x) SHA##x##_Update +#define SHA_Update(x) _SHA_Update(x) + +#define _SHA_Final(x) SHA##x##_Final +#define SHA_Final(x) _SHA_Final(x) + +#define _SHA_End(x) SHA##x##_End +#define SHA_End(x) _SHA_End(x) + +#define _SHA_File(x) SHA##x##_File +#define SHA_File(x) _SHA_File(x) + +#define _SHA_FileChunk(x) SHA##x##_FileChunk +#define SHA_FileChunk(x) _SHA_FileChunk(x) + +#define _SHA_Data(x) SHA##x##_Data +#define SHA_Data(x) _SHA_Data(x) + +void test1() { + SHA_CTX(SHASIZE) ctx; + uint8_t entropy[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; + uint8_t digest[SHA_DIGEST_LENGTH(SHASIZE)]; + + SHA_Init(SHASIZE)(&ctx); + SHA_Update(SHASIZE)(&ctx, entropy, __arraycount(entropy)); + SHA_Final(SHASIZE)(digest, &ctx); + + printf("test1: '"); + for (size_t i = 0; i < __arraycount(digest); i++) + printf("%02x", digest[i]); + printf("'\n"); +} + +void test2() { + SHA_CTX(SHASIZE) ctx; + uint8_t entropy[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; + char digest[SHA_DIGEST_STRING_LENGTH(SHASIZE)]; + + SHA_Init(SHASIZE)(&ctx); + SHA_Update(SHASIZE)(&ctx, entropy, __arraycount(entropy)); + char *p = SHA_End(SHASIZE)(&ctx, digest); + assert(p == digest); + + printf("test2: '%s'\n", digest); +} + +void test3() { + SHA_CTX(SHASIZE) ctx; + uint8_t entropy[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; + + SHA_Init(SHASIZE)(&ctx); + SHA_Update(SHASIZE)(&ctx, entropy, __arraycount(entropy)); + char *p = SHA_End(SHASIZE)(&ctx, NULL); + assert(strlen(p) == SHA_DIGEST_STRING_LENGTH(SHASIZE) - 1); + + printf("test3: '%s'\n", p); + + free(p); +} + +void test4() { + char digest[SHA_DIGEST_STRING_LENGTH(SHASIZE)]; + + char *p = SHA_File(SHASIZE)("/etc/fstab", digest); + assert(p == digest); + + printf("test4: '%s'\n", p); +} + +void test5() { + char *p = SHA_File(SHASIZE)("/etc/fstab", NULL); + assert(strlen(p) == SHA_DIGEST_STRING_LENGTH(SHASIZE) - 1); + + printf("test5: '%s'\n", p); + + free(p); +} + +void test6() { + char digest[SHA_DIGEST_STRING_LENGTH(SHASIZE)]; + + char *p = SHA_FileChunk(SHASIZE)("/etc/fstab", digest, 10, 20); + assert(p == digest); + + printf("test6: '%s'\n", p); +} + +void test7() { + char *p = SHA_FileChunk(SHASIZE)("/etc/fstab", NULL, 10, 20); + assert(strlen(p) == SHA_DIGEST_STRING_LENGTH(SHASIZE) - 1); + + printf("test7: '%s'\n", p); + + free(p); +} + +void test8() { + uint8_t entropy[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; + char digest[SHA_DIGEST_STRING_LENGTH(SHASIZE)]; + + char *p = SHA_Data(SHASIZE)(entropy, __arraycount(entropy), digest); + assert(p == digest); + + printf("test8: '%s'\n", p); +} + +void test9() { + uint8_t entropy[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; + + char *p = SHA_Data(SHASIZE)(entropy, __arraycount(entropy), NULL); + assert(strlen(p) == SHA_DIGEST_STRING_LENGTH(SHASIZE) - 1); + + printf("test9: '%s'\n", p); + + free(p); +} + +int main(void) { + printf("SHA" ___STRING(SHASIZE) "\n"); + + test1(); + test2(); + test3(); + test4(); + test5(); + test6(); + test7(); + test8(); + test9(); + + // CHECK-224: SHA224 + // CHECK-224: test1: '760dfb93100a6bf5996c90f678e529dc945bb2f74a211eedcf0f3a48' + // CHECK-224: test2: '760dfb93100a6bf5996c90f678e529dc945bb2f74a211eedcf0f3a48' + // CHECK-224: test3: '760dfb93100a6bf5996c90f678e529dc945bb2f74a211eedcf0f3a48' + // CHECK-224: test4: '{{.*}}' + // CHECK-224: test5: '{{.*}}' + // CHECK-224: test6: '{{.*}}' + // CHECK-224: test7: '{{.*}}' + // CHECK-224: test8: '760dfb93100a6bf5996c90f678e529dc945bb2f74a211eedcf0f3a48' + // CHECK-224: test9: '760dfb93100a6bf5996c90f678e529dc945bb2f74a211eedcf0f3a48' + + // CHECK-256: SHA256 + // CHECK-256: test1: 'bb000ddd92a0a2a346f0b531f278af06e370f86932ccafccc892d68d350f80f8' + // CHECK-256: test2: 'bb000ddd92a0a2a346f0b531f278af06e370f86932ccafccc892d68d350f80f8' + // CHECK-256: test3: 'bb000ddd92a0a2a346f0b531f278af06e370f86932ccafccc892d68d350f80f8' + // CHECK-256: test4: 'bb058583870ed830d9b74b4c24af7fa2ab5684f4d88158a8094a68bcf908dc48' + // CHECK-256: test5: 'bb058583870ed830d9b74b4c24af7fa2ab5684f4d88158a8094a68bcf908dc48' + // CHECK-256: test6: 'cc1c596e07913a44fe35a4d4fd76b4bd6313604fa4264e2e6fbae1db78c24b22' + // CHECK-256: test7: 'cc1c596e07913a44fe35a4d4fd76b4bd6313604fa4264e2e6fbae1db78c24b22' + // CHECK-256: test8: 'bb000ddd92a0a2a346f0b531f278af06e370f86932ccafccc892d68d350f80f8' + // CHECK-256: test9: 'bb000ddd92a0a2a346f0b531f278af06e370f86932ccafccc892d68d350f80f8' + + // CHECK-384: SHA384 + // CHECK-384: test1: 'f450c023b168ebd56ff916ca9b1f1f0010b8c592d28205cc91fa3056f629eed108e8bac864f01ca37a3edee596739e12' + // CHECK-384: test2: 'f450c023b168ebd56ff916ca9b1f1f0010b8c592d28205cc91fa3056f629eed108e8bac864f01ca37a3edee596739e12' + // CHECK-384: test3: 'f450c023b168ebd56ff916ca9b1f1f0010b8c592d28205cc91fa3056f629eed108e8bac864f01ca37a3edee596739e12' + // CHECK-384: test4: '330d1528c9828d46e200fbfe05cac41717bed2e5f87ba10d47c9d6098e94f5e902ad90d4dd9be0f4347bc026e1206abd' + // CHECK-384: test5: '330d1528c9828d46e200fbfe05cac41717bed2e5f87ba10d47c9d6098e94f5e902ad90d4dd9be0f4347bc026e1206abd' + // CHECK-384: test6: '60686e8385598c69a2309483b91c04a1e0deeef1201730607a1818d097e726a9cbde8f8b8de7ab76c1d347def17f5ab5' + // CHECK-384: test7: '60686e8385598c69a2309483b91c04a1e0deeef1201730607a1818d097e726a9cbde8f8b8de7ab76c1d347def17f5ab5' + // CHECK-384: test8: 'f450c023b168ebd56ff916ca9b1f1f0010b8c592d28205cc91fa3056f629eed108e8bac864f01ca37a3edee596739e12' + // CHECK-384: test9: 'f450c023b168ebd56ff916ca9b1f1f0010b8c592d28205cc91fa3056f629eed108e8bac864f01ca37a3edee596739e12' + + // CHECK-512: SHA512 + // CHECK-512: test1: '0e3f68731c0e2a6a4eab5d713c9a80dc78086b5fa7d2b5ab127277958e68d1b1dee1882b083b0106cd4319de42c0c8f452871364f5baa8a6379690612c6b844e' + // CHECK-512: test2: '0e3f68731c0e2a6a4eab5d713c9a80dc78086b5fa7d2b5ab127277958e68d1b1dee1882b083b0106cd4319de42c0c8f452871364f5baa8a6379690612c6b844e' + // CHECK-512: test3: '0e3f68731c0e2a6a4eab5d713c9a80dc78086b5fa7d2b5ab127277958e68d1b1dee1882b083b0106cd4319de42c0c8f452871364f5baa8a6379690612c6b844e' + // CHECK-512: test4: '56b925cd62d73643e0f5ab821e062be9157035652cfb6396cb08d84f88981b1a9dae79f3d2707ad4f821d86b5608ae93f71788724328bb6e4ed1704a985d07a7' + // CHECK-512: test5: '56b925cd62d73643e0f5ab821e062be9157035652cfb6396cb08d84f88981b1a9dae79f3d2707ad4f821d86b5608ae93f71788724328bb6e4ed1704a985d07a7' + // CHECK-512: test6: '273b577200f95cfcb1627d94c0e6f3dd1682f63b4dfcc315355a7b90586e4cfd8f65c7cb315bd2b29c7ec0942510ffaceb1f02c7041f45528a6357fd38f2fe39' + // CHECK-512: test7: '273b577200f95cfcb1627d94c0e6f3dd1682f63b4dfcc315355a7b90586e4cfd8f65c7cb315bd2b29c7ec0942510ffaceb1f02c7041f45528a6357fd38f2fe39' + // CHECK-512: test8: '0e3f68731c0e2a6a4eab5d713c9a80dc78086b5fa7d2b5ab127277958e68d1b1dee1882b083b0106cd4319de42c0c8f452871364f5baa8a6379690612c6b844e' + // CHECK-512: test9: '0e3f68731c0e2a6a4eab5d713c9a80dc78086b5fa7d2b5ab127277958e68d1b1dee1882b083b0106cd4319de42c0c8f452871364f5baa8a6379690612c6b844e' + + return 0; +}