check.h revision 292588
1///////////////////////////////////////////////////////////////////////////////
2//
3/// \file       check.h
4/// \brief      Internal API to different integrity check functions
5//
6//  Author:     Lasse Collin
7//
8//  This file has been put into the public domain.
9//  You can do whatever you want with this file.
10//
11///////////////////////////////////////////////////////////////////////////////
12
13#ifndef LZMA_CHECK_H
14#define LZMA_CHECK_H
15
16#include "common.h"
17
18#if defined(HAVE_COMMONCRYPTO_COMMONDIGEST_H)
19#	include <CommonCrypto/CommonDigest.h>
20#elif defined(HAVE_SHA256_H)
21#	include <sys/types.h>
22#	include <sha256.h>
23#elif defined(HAVE_SHA2_H)
24#	include <sys/types.h>
25#	include <sha2.h>
26#elif defined(HAVE_MINIX_SHA2_H)
27#	include <sys/types.h>
28#	include <minix/sha2.h>
29#endif
30
31#if defined(HAVE_CC_SHA256_CTX)
32typedef CC_SHA256_CTX lzma_sha256_state;
33#elif defined(HAVE_SHA256_CTX)
34typedef SHA256_CTX lzma_sha256_state;
35#elif defined(HAVE_SHA2_CTX)
36typedef SHA2_CTX lzma_sha256_state;
37#else
38/// State for the internal SHA-256 implementation
39typedef struct {
40	/// Internal state
41	uint32_t state[8];
42
43	/// Size of the message excluding padding
44	uint64_t size;
45} lzma_sha256_state;
46#endif
47
48#if defined(HAVE_CC_SHA256_INIT)
49#	define LZMA_SHA256FUNC(x) CC_SHA256_ ## x
50#elif defined(HAVE_SHA256_INIT)
51#	define LZMA_SHA256FUNC(x) SHA256_ ## x
52#elif defined(HAVE_SHA256INIT)
53#	define LZMA_SHA256FUNC(x) SHA256 ## x
54#endif
55
56// Index hashing needs the best possible hash function (preferably
57// a cryptographic hash) for maximum reliability.
58#if defined(HAVE_CHECK_SHA256)
59#	define LZMA_CHECK_BEST LZMA_CHECK_SHA256
60#elif defined(HAVE_CHECK_CRC64)
61#	define LZMA_CHECK_BEST LZMA_CHECK_CRC64
62#else
63#	define LZMA_CHECK_BEST LZMA_CHECK_CRC32
64#endif
65
66
67/// \brief      Structure to hold internal state of the check being calculated
68///
69/// \note       This is not in the public API because this structure may
70///             change in future if new integrity check algorithms are added.
71typedef struct {
72	/// Buffer to hold the final result and a temporary buffer for SHA256.
73	union {
74		uint8_t u8[64];
75		uint32_t u32[16];
76		uint64_t u64[8];
77	} buffer;
78
79	/// Check-specific data
80	union {
81		uint32_t crc32;
82		uint64_t crc64;
83		lzma_sha256_state sha256;
84	} state;
85
86} lzma_check_state;
87
88
89/// lzma_crc32_table[0] is needed by LZ encoder so we need to keep
90/// the array two-dimensional.
91#ifdef HAVE_SMALL
92extern uint32_t lzma_crc32_table[1][256];
93extern void lzma_crc32_init(void);
94#else
95extern const uint32_t lzma_crc32_table[8][256];
96extern const uint64_t lzma_crc64_table[4][256];
97#endif
98
99
100/// \brief      Initialize *check depending on type
101///
102/// \return     LZMA_OK on success. LZMA_UNSUPPORTED_CHECK if the type is not
103///             supported by the current version or build of liblzma.
104///             LZMA_PROG_ERROR if type > LZMA_CHECK_ID_MAX.
105extern void lzma_check_init(lzma_check_state *check, lzma_check type);
106
107/// Update the check state
108extern void lzma_check_update(lzma_check_state *check, lzma_check type,
109		const uint8_t *buf, size_t size);
110
111/// Finish the check calculation and store the result to check->buffer.u8.
112extern void lzma_check_finish(lzma_check_state *check, lzma_check type);
113
114
115#ifndef LZMA_SHA256FUNC
116
117/// Prepare SHA-256 state for new input.
118extern void lzma_sha256_init(lzma_check_state *check);
119
120/// Update the SHA-256 hash state
121extern void lzma_sha256_update(
122		const uint8_t *buf, size_t size, lzma_check_state *check);
123
124/// Finish the SHA-256 calculation and store the result to check->buffer.u8.
125extern void lzma_sha256_finish(lzma_check_state *check);
126
127
128#else
129
130static inline void
131lzma_sha256_init(lzma_check_state *check)
132{
133	LZMA_SHA256FUNC(Init)(&check->state.sha256);
134}
135
136
137static inline void
138lzma_sha256_update(const uint8_t *buf, size_t size, lzma_check_state *check)
139{
140#if defined(HAVE_CC_SHA256_INIT) && SIZE_MAX > UINT32_MAX
141	// Darwin's CC_SHA256_Update takes uint32_t as the buffer size,
142	// so use a loop to support size_t.
143	while (size > UINT32_MAX) {
144		LZMA_SHA256FUNC(Update)(&check->state.sha256, buf, UINT32_MAX);
145		buf += UINT32_MAX;
146		size -= UINT32_MAX;
147	}
148#endif
149
150	LZMA_SHA256FUNC(Update)(&check->state.sha256, buf, size);
151}
152
153
154static inline void
155lzma_sha256_finish(lzma_check_state *check)
156{
157	LZMA_SHA256FUNC(Final)(check->buffer.u8, &check->state.sha256);
158}
159
160#endif
161
162#endif
163