1207753Smm///////////////////////////////////////////////////////////////////////////////
2207753Smm//
3207753Smm/// \file       check.h
4207753Smm/// \brief      Internal API to different integrity check functions
5207753Smm//
6207753Smm//  Author:     Lasse Collin
7207753Smm//
8207753Smm//  This file has been put into the public domain.
9207753Smm//  You can do whatever you want with this file.
10207753Smm//
11207753Smm///////////////////////////////////////////////////////////////////////////////
12207753Smm
13207753Smm#ifndef LZMA_CHECK_H
14207753Smm#define LZMA_CHECK_H
15207753Smm
16207753Smm#include "common.h"
17207753Smm
18312517Sdelphij// If the function for external SHA-256 is missing, use the internal SHA-256
19312517Sdelphij// code. Due to how configure works, these defines can only get defined when
20312517Sdelphij// both a usable header and a type have already been found.
21312517Sdelphij#if !(defined(HAVE_CC_SHA256_INIT) \
22312517Sdelphij		|| defined(HAVE_SHA256_INIT) \
23312517Sdelphij		|| defined(HAVE_SHA256INIT))
24312517Sdelphij#	define HAVE_INTERNAL_SHA256 1
25312517Sdelphij#endif
26312517Sdelphij
27312517Sdelphij#if defined(HAVE_INTERNAL_SHA256)
28312517Sdelphij// Nothing
29312517Sdelphij#elif defined(HAVE_COMMONCRYPTO_COMMONDIGEST_H)
30278433Srpaulo#	include <CommonCrypto/CommonDigest.h>
31278433Srpaulo#elif defined(HAVE_SHA256_H)
32278433Srpaulo#	include <sys/types.h>
33278433Srpaulo#	include <sha256.h>
34278433Srpaulo#elif defined(HAVE_SHA2_H)
35278433Srpaulo#	include <sys/types.h>
36278433Srpaulo#	include <sha2.h>
37278433Srpaulo#endif
38207753Smm
39312517Sdelphij#if defined(HAVE_INTERNAL_SHA256)
40278433Srpaulo/// State for the internal SHA-256 implementation
41278433Srpaulotypedef struct {
42278433Srpaulo	/// Internal state
43278433Srpaulo	uint32_t state[8];
44278433Srpaulo
45278433Srpaulo	/// Size of the message excluding padding
46278433Srpaulo	uint64_t size;
47278433Srpaulo} lzma_sha256_state;
48312517Sdelphij#elif defined(HAVE_CC_SHA256_CTX)
49312517Sdelphijtypedef CC_SHA256_CTX lzma_sha256_state;
50312517Sdelphij#elif defined(HAVE_SHA256_CTX)
51312517Sdelphijtypedef SHA256_CTX lzma_sha256_state;
52312517Sdelphij#elif defined(HAVE_SHA2_CTX)
53312517Sdelphijtypedef SHA2_CTX lzma_sha256_state;
54278433Srpaulo#endif
55278433Srpaulo
56312517Sdelphij#if defined(HAVE_INTERNAL_SHA256)
57312517Sdelphij// Nothing
58312517Sdelphij#elif defined(HAVE_CC_SHA256_INIT)
59278433Srpaulo#	define LZMA_SHA256FUNC(x) CC_SHA256_ ## x
60278433Srpaulo#elif defined(HAVE_SHA256_INIT)
61278433Srpaulo#	define LZMA_SHA256FUNC(x) SHA256_ ## x
62278433Srpaulo#elif defined(HAVE_SHA256INIT)
63278433Srpaulo#	define LZMA_SHA256FUNC(x) SHA256 ## x
64278433Srpaulo#endif
65278433Srpaulo
66207753Smm// Index hashing needs the best possible hash function (preferably
67207753Smm// a cryptographic hash) for maximum reliability.
68207753Smm#if defined(HAVE_CHECK_SHA256)
69207753Smm#	define LZMA_CHECK_BEST LZMA_CHECK_SHA256
70207753Smm#elif defined(HAVE_CHECK_CRC64)
71207753Smm#	define LZMA_CHECK_BEST LZMA_CHECK_CRC64
72207753Smm#else
73207753Smm#	define LZMA_CHECK_BEST LZMA_CHECK_CRC32
74207753Smm#endif
75207753Smm
76207753Smm
77207753Smm/// \brief      Structure to hold internal state of the check being calculated
78207753Smm///
79207753Smm/// \note       This is not in the public API because this structure may
80207753Smm///             change in future if new integrity check algorithms are added.
81207753Smmtypedef struct {
82207753Smm	/// Buffer to hold the final result and a temporary buffer for SHA256.
83207753Smm	union {
84207753Smm		uint8_t u8[64];
85207753Smm		uint32_t u32[16];
86207753Smm		uint64_t u64[8];
87207753Smm	} buffer;
88207753Smm
89207753Smm	/// Check-specific data
90207753Smm	union {
91207753Smm		uint32_t crc32;
92207753Smm		uint64_t crc64;
93278433Srpaulo		lzma_sha256_state sha256;
94207753Smm	} state;
95207753Smm
96207753Smm} lzma_check_state;
97207753Smm
98207753Smm
99207753Smm/// lzma_crc32_table[0] is needed by LZ encoder so we need to keep
100207753Smm/// the array two-dimensional.
101207753Smm#ifdef HAVE_SMALL
102207753Smmextern uint32_t lzma_crc32_table[1][256];
103207753Smmextern void lzma_crc32_init(void);
104207753Smm#else
105207753Smmextern const uint32_t lzma_crc32_table[8][256];
106207753Smmextern const uint64_t lzma_crc64_table[4][256];
107207753Smm#endif
108207753Smm
109207753Smm
110207753Smm/// \brief      Initialize *check depending on type
111207753Smm///
112207753Smm/// \return     LZMA_OK on success. LZMA_UNSUPPORTED_CHECK if the type is not
113207753Smm///             supported by the current version or build of liblzma.
114207753Smm///             LZMA_PROG_ERROR if type > LZMA_CHECK_ID_MAX.
115207753Smmextern void lzma_check_init(lzma_check_state *check, lzma_check type);
116207753Smm
117207753Smm/// Update the check state
118207753Smmextern void lzma_check_update(lzma_check_state *check, lzma_check type,
119207753Smm		const uint8_t *buf, size_t size);
120207753Smm
121207753Smm/// Finish the check calculation and store the result to check->buffer.u8.
122207753Smmextern void lzma_check_finish(lzma_check_state *check, lzma_check type);
123207753Smm
124207753Smm
125278433Srpaulo#ifndef LZMA_SHA256FUNC
126278433Srpaulo
127207753Smm/// Prepare SHA-256 state for new input.
128207753Smmextern void lzma_sha256_init(lzma_check_state *check);
129207753Smm
130207753Smm/// Update the SHA-256 hash state
131207753Smmextern void lzma_sha256_update(
132207753Smm		const uint8_t *buf, size_t size, lzma_check_state *check);
133207753Smm
134207753Smm/// Finish the SHA-256 calculation and store the result to check->buffer.u8.
135207753Smmextern void lzma_sha256_finish(lzma_check_state *check);
136207753Smm
137278433Srpaulo
138278433Srpaulo#else
139278433Srpaulo
140278433Srpaulostatic inline void
141278433Srpaulolzma_sha256_init(lzma_check_state *check)
142278433Srpaulo{
143278433Srpaulo	LZMA_SHA256FUNC(Init)(&check->state.sha256);
144278433Srpaulo}
145278433Srpaulo
146278433Srpaulo
147278433Srpaulostatic inline void
148278433Srpaulolzma_sha256_update(const uint8_t *buf, size_t size, lzma_check_state *check)
149278433Srpaulo{
150278433Srpaulo#if defined(HAVE_CC_SHA256_INIT) && SIZE_MAX > UINT32_MAX
151278433Srpaulo	// Darwin's CC_SHA256_Update takes uint32_t as the buffer size,
152278433Srpaulo	// so use a loop to support size_t.
153278433Srpaulo	while (size > UINT32_MAX) {
154278433Srpaulo		LZMA_SHA256FUNC(Update)(&check->state.sha256, buf, UINT32_MAX);
155278433Srpaulo		buf += UINT32_MAX;
156278433Srpaulo		size -= UINT32_MAX;
157278433Srpaulo	}
158207753Smm#endif
159278433Srpaulo
160278433Srpaulo	LZMA_SHA256FUNC(Update)(&check->state.sha256, buf, size);
161278433Srpaulo}
162278433Srpaulo
163278433Srpaulo
164278433Srpaulostatic inline void
165278433Srpaulolzma_sha256_finish(lzma_check_state *check)
166278433Srpaulo{
167278433Srpaulo	LZMA_SHA256FUNC(Final)(check->buffer.u8, &check->state.sha256);
168278433Srpaulo}
169278433Srpaulo
170278433Srpaulo#endif
171278433Srpaulo
172278433Srpaulo#endif
173