xref: /freebsd/contrib/xz/src/liblzma/check/check.h (revision 128836d304d93f2d00eb14069c27089ab46c38d4)
1*3b35e7eeSXin LI // SPDX-License-Identifier: 0BSD
2*3b35e7eeSXin LI 
381ad8388SMartin Matuska ///////////////////////////////////////////////////////////////////////////////
481ad8388SMartin Matuska //
581ad8388SMartin Matuska /// \file       check.h
681ad8388SMartin Matuska /// \brief      Internal API to different integrity check functions
781ad8388SMartin Matuska //
881ad8388SMartin Matuska //  Author:     Lasse Collin
981ad8388SMartin Matuska //
1081ad8388SMartin Matuska ///////////////////////////////////////////////////////////////////////////////
1181ad8388SMartin Matuska 
1281ad8388SMartin Matuska #ifndef LZMA_CHECK_H
1381ad8388SMartin Matuska #define LZMA_CHECK_H
1481ad8388SMartin Matuska 
1581ad8388SMartin Matuska #include "common.h"
1681ad8388SMartin Matuska 
171456f0f9SXin LI // If the function for external SHA-256 is missing, use the internal SHA-256
181456f0f9SXin LI // code. Due to how configure works, these defines can only get defined when
191456f0f9SXin LI // both a usable header and a type have already been found.
201456f0f9SXin LI #if !(defined(HAVE_CC_SHA256_INIT) \
211456f0f9SXin LI 		|| defined(HAVE_SHA256_INIT) \
221456f0f9SXin LI 		|| defined(HAVE_SHA256INIT))
231456f0f9SXin LI #	define HAVE_INTERNAL_SHA256 1
241456f0f9SXin LI #endif
251456f0f9SXin LI 
261456f0f9SXin LI #if defined(HAVE_INTERNAL_SHA256)
271456f0f9SXin LI // Nothing
281456f0f9SXin LI #elif defined(HAVE_COMMONCRYPTO_COMMONDIGEST_H)
2953200025SRui Paulo #	include <CommonCrypto/CommonDigest.h>
3053200025SRui Paulo #elif defined(HAVE_SHA256_H)
3153200025SRui Paulo #	include <sys/types.h>
3253200025SRui Paulo #	include <sha256.h>
3353200025SRui Paulo #elif defined(HAVE_SHA2_H)
3453200025SRui Paulo #	include <sys/types.h>
3553200025SRui Paulo #	include <sha2.h>
3653200025SRui Paulo #endif
3753200025SRui Paulo 
381456f0f9SXin LI #if defined(HAVE_INTERNAL_SHA256)
3953200025SRui Paulo /// State for the internal SHA-256 implementation
4053200025SRui Paulo typedef struct {
4153200025SRui Paulo 	/// Internal state
4253200025SRui Paulo 	uint32_t state[8];
4353200025SRui Paulo 
4453200025SRui Paulo 	/// Size of the message excluding padding
4553200025SRui Paulo 	uint64_t size;
4653200025SRui Paulo } lzma_sha256_state;
471456f0f9SXin LI #elif defined(HAVE_CC_SHA256_CTX)
481456f0f9SXin LI typedef CC_SHA256_CTX lzma_sha256_state;
491456f0f9SXin LI #elif defined(HAVE_SHA256_CTX)
501456f0f9SXin LI typedef SHA256_CTX lzma_sha256_state;
511456f0f9SXin LI #elif defined(HAVE_SHA2_CTX)
521456f0f9SXin LI typedef SHA2_CTX lzma_sha256_state;
5353200025SRui Paulo #endif
5453200025SRui Paulo 
551456f0f9SXin LI #if defined(HAVE_INTERNAL_SHA256)
561456f0f9SXin LI // Nothing
571456f0f9SXin LI #elif defined(HAVE_CC_SHA256_INIT)
5853200025SRui Paulo #	define LZMA_SHA256FUNC(x) CC_SHA256_ ## x
5953200025SRui Paulo #elif defined(HAVE_SHA256_INIT)
6053200025SRui Paulo #	define LZMA_SHA256FUNC(x) SHA256_ ## x
6153200025SRui Paulo #elif defined(HAVE_SHA256INIT)
6253200025SRui Paulo #	define LZMA_SHA256FUNC(x) SHA256 ## x
6353200025SRui Paulo #endif
6481ad8388SMartin Matuska 
6581ad8388SMartin Matuska // Index hashing needs the best possible hash function (preferably
6681ad8388SMartin Matuska // a cryptographic hash) for maximum reliability.
6781ad8388SMartin Matuska #if defined(HAVE_CHECK_SHA256)
6881ad8388SMartin Matuska #	define LZMA_CHECK_BEST LZMA_CHECK_SHA256
6981ad8388SMartin Matuska #elif defined(HAVE_CHECK_CRC64)
7081ad8388SMartin Matuska #	define LZMA_CHECK_BEST LZMA_CHECK_CRC64
7181ad8388SMartin Matuska #else
7281ad8388SMartin Matuska #	define LZMA_CHECK_BEST LZMA_CHECK_CRC32
7381ad8388SMartin Matuska #endif
7481ad8388SMartin Matuska 
7581ad8388SMartin Matuska 
7681ad8388SMartin Matuska /// \brief      Structure to hold internal state of the check being calculated
7781ad8388SMartin Matuska ///
7881ad8388SMartin Matuska /// \note       This is not in the public API because this structure may
7981ad8388SMartin Matuska ///             change in future if new integrity check algorithms are added.
8081ad8388SMartin Matuska typedef struct {
8181ad8388SMartin Matuska 	/// Buffer to hold the final result and a temporary buffer for SHA256.
8281ad8388SMartin Matuska 	union {
8381ad8388SMartin Matuska 		uint8_t u8[64];
8481ad8388SMartin Matuska 		uint32_t u32[16];
8581ad8388SMartin Matuska 		uint64_t u64[8];
8681ad8388SMartin Matuska 	} buffer;
8781ad8388SMartin Matuska 
8881ad8388SMartin Matuska 	/// Check-specific data
8981ad8388SMartin Matuska 	union {
9081ad8388SMartin Matuska 		uint32_t crc32;
9181ad8388SMartin Matuska 		uint64_t crc64;
9253200025SRui Paulo 		lzma_sha256_state sha256;
9381ad8388SMartin Matuska 	} state;
9481ad8388SMartin Matuska 
9581ad8388SMartin Matuska } lzma_check_state;
9681ad8388SMartin Matuska 
9781ad8388SMartin Matuska 
9881ad8388SMartin Matuska /// \brief      Initialize *check depending on type
9981ad8388SMartin Matuska extern void lzma_check_init(lzma_check_state *check, lzma_check type);
10081ad8388SMartin Matuska 
10181ad8388SMartin Matuska /// Update the check state
10281ad8388SMartin Matuska extern void lzma_check_update(lzma_check_state *check, lzma_check type,
10381ad8388SMartin Matuska 		const uint8_t *buf, size_t size);
10481ad8388SMartin Matuska 
10581ad8388SMartin Matuska /// Finish the check calculation and store the result to check->buffer.u8.
10681ad8388SMartin Matuska extern void lzma_check_finish(lzma_check_state *check, lzma_check type);
10781ad8388SMartin Matuska 
10881ad8388SMartin Matuska 
10953200025SRui Paulo #ifndef LZMA_SHA256FUNC
11053200025SRui Paulo 
11181ad8388SMartin Matuska /// Prepare SHA-256 state for new input.
11281ad8388SMartin Matuska extern void lzma_sha256_init(lzma_check_state *check);
11381ad8388SMartin Matuska 
11481ad8388SMartin Matuska /// Update the SHA-256 hash state
11581ad8388SMartin Matuska extern void lzma_sha256_update(
11681ad8388SMartin Matuska 		const uint8_t *buf, size_t size, lzma_check_state *check);
11781ad8388SMartin Matuska 
11881ad8388SMartin Matuska /// Finish the SHA-256 calculation and store the result to check->buffer.u8.
11981ad8388SMartin Matuska extern void lzma_sha256_finish(lzma_check_state *check);
12081ad8388SMartin Matuska 
12153200025SRui Paulo 
12253200025SRui Paulo #else
12353200025SRui Paulo 
12453200025SRui Paulo static inline void
lzma_sha256_init(lzma_check_state * check)12553200025SRui Paulo lzma_sha256_init(lzma_check_state *check)
12653200025SRui Paulo {
12753200025SRui Paulo 	LZMA_SHA256FUNC(Init)(&check->state.sha256);
12853200025SRui Paulo }
12953200025SRui Paulo 
13053200025SRui Paulo 
13153200025SRui Paulo static inline void
lzma_sha256_update(const uint8_t * buf,size_t size,lzma_check_state * check)13253200025SRui Paulo lzma_sha256_update(const uint8_t *buf, size_t size, lzma_check_state *check)
13353200025SRui Paulo {
13453200025SRui Paulo #if defined(HAVE_CC_SHA256_INIT) && SIZE_MAX > UINT32_MAX
13553200025SRui Paulo 	// Darwin's CC_SHA256_Update takes uint32_t as the buffer size,
13653200025SRui Paulo 	// so use a loop to support size_t.
13753200025SRui Paulo 	while (size > UINT32_MAX) {
13853200025SRui Paulo 		LZMA_SHA256FUNC(Update)(&check->state.sha256, buf, UINT32_MAX);
13953200025SRui Paulo 		buf += UINT32_MAX;
14053200025SRui Paulo 		size -= UINT32_MAX;
14153200025SRui Paulo 	}
14253200025SRui Paulo #endif
14353200025SRui Paulo 
14453200025SRui Paulo 	LZMA_SHA256FUNC(Update)(&check->state.sha256, buf, size);
14553200025SRui Paulo }
14653200025SRui Paulo 
14753200025SRui Paulo 
14853200025SRui Paulo static inline void
lzma_sha256_finish(lzma_check_state * check)14953200025SRui Paulo lzma_sha256_finish(lzma_check_state *check)
15053200025SRui Paulo {
15153200025SRui Paulo 	LZMA_SHA256FUNC(Final)(check->buffer.u8, &check->state.sha256);
15253200025SRui Paulo }
15353200025SRui Paulo 
15453200025SRui Paulo #endif
15553200025SRui Paulo 
15681ad8388SMartin Matuska #endif
157