1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 /// \file       check.c
4 /// \brief      Single API to access different integrity checks
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 #include "check.h"
14 
15 
16 extern LZMA_API(lzma_bool)
lzma_check_is_supported(lzma_check type)17 lzma_check_is_supported(lzma_check type)
18 {
19 	if ((unsigned int)(type) > LZMA_CHECK_ID_MAX)
20 		return false;
21 
22 	static const lzma_bool available_checks[LZMA_CHECK_ID_MAX + 1] = {
23 		true,   // LZMA_CHECK_NONE
24 
25 #ifdef HAVE_CHECK_CRC32
26 		true,
27 #else
28 		false,
29 #endif
30 
31 		false,  // Reserved
32 		false,  // Reserved
33 
34 #ifdef HAVE_CHECK_CRC64
35 		true,
36 #else
37 		false,
38 #endif
39 
40 		false,  // Reserved
41 		false,  // Reserved
42 		false,  // Reserved
43 		false,  // Reserved
44 		false,  // Reserved
45 
46 #ifdef HAVE_CHECK_SHA256
47 		true,
48 #else
49 		false,
50 #endif
51 
52 		false,  // Reserved
53 		false,  // Reserved
54 		false,  // Reserved
55 		false,  // Reserved
56 		false,  // Reserved
57 	};
58 
59 	return available_checks[(unsigned int)(type)];
60 }
61 
62 
63 extern LZMA_API(uint32_t)
lzma_check_size(lzma_check type)64 lzma_check_size(lzma_check type)
65 {
66 	if ((unsigned int)(type) > LZMA_CHECK_ID_MAX)
67 		return UINT32_MAX;
68 
69 	// See file-format.txt section 2.1.1.2.
70 	static const uint8_t check_sizes[LZMA_CHECK_ID_MAX + 1] = {
71 		0,
72 		4, 4, 4,
73 		8, 8, 8,
74 		16, 16, 16,
75 		32, 32, 32,
76 		64, 64, 64
77 	};
78 
79 	return check_sizes[(unsigned int)(type)];
80 }
81 
82 
83 extern void
lzma_check_init(lzma_check_state * check,lzma_check type)84 lzma_check_init(lzma_check_state *check, lzma_check type)
85 {
86 	switch (type) {
87 	case LZMA_CHECK_NONE:
88 		break;
89 
90 #ifdef HAVE_CHECK_CRC32
91 	case LZMA_CHECK_CRC32:
92 		check->state.crc32 = 0;
93 		break;
94 #endif
95 
96 #ifdef HAVE_CHECK_CRC64
97 	case LZMA_CHECK_CRC64:
98 		check->state.crc64 = 0;
99 		break;
100 #endif
101 
102 #ifdef HAVE_CHECK_SHA256
103 	case LZMA_CHECK_SHA256:
104 		lzma_sha256_init(check);
105 		break;
106 #endif
107 
108 	default:
109 		break;
110 	}
111 
112 	return;
113 }
114 
115 
116 extern void
lzma_check_update(lzma_check_state * check,lzma_check type,const uint8_t * buf,size_t size)117 lzma_check_update(lzma_check_state *check, lzma_check type,
118 		const uint8_t *buf, size_t size)
119 {
120 	switch (type) {
121 #ifdef HAVE_CHECK_CRC32
122 	case LZMA_CHECK_CRC32:
123 		check->state.crc32 = lzma_crc32(buf, size, check->state.crc32);
124 		break;
125 #endif
126 
127 #ifdef HAVE_CHECK_CRC64
128 	case LZMA_CHECK_CRC64:
129 		check->state.crc64 = lzma_crc64(buf, size, check->state.crc64);
130 		break;
131 #endif
132 
133 #ifdef HAVE_CHECK_SHA256
134 	case LZMA_CHECK_SHA256:
135 		lzma_sha256_update(buf, size, check);
136 		break;
137 #endif
138 
139 	default:
140 		break;
141 	}
142 
143 	return;
144 }
145 
146 
147 extern void
lzma_check_finish(lzma_check_state * check,lzma_check type)148 lzma_check_finish(lzma_check_state *check, lzma_check type)
149 {
150 	switch (type) {
151 #ifdef HAVE_CHECK_CRC32
152 	case LZMA_CHECK_CRC32:
153 		check->buffer.u32[0] = conv32le(check->state.crc32);
154 		break;
155 #endif
156 
157 #ifdef HAVE_CHECK_CRC64
158 	case LZMA_CHECK_CRC64:
159 		check->buffer.u64[0] = conv64le(check->state.crc64);
160 		break;
161 #endif
162 
163 #ifdef HAVE_CHECK_SHA256
164 	case LZMA_CHECK_SHA256:
165 		lzma_sha256_finish(check);
166 		break;
167 #endif
168 
169 	default:
170 		break;
171 	}
172 
173 	return;
174 }
175