1 /*
2  * $Id: ebmlcrc.c 642 2010-11-28 08:38:47Z robux4 $
3  * Copyright (c) 2008-2010, Matroska (non-profit organisation)
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *     * Redistributions of source code must retain the above copyright
9  *       notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above copyright
11  *       notice, this list of conditions and the following disclaimer in the
12  *       documentation and/or other materials provided with the distribution.
13  *     * Neither the name of the Matroska assocation nor the
14  *       names of its contributors may be used to endorse or promote products
15  *       derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY the Matroska association ``AS IS'' AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL The Matroska Foundation BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 #include "ebml/ebml.h"
29 #include "ebml/ebml_internal.h"
30 
31 struct ebml_crc
32 {
33     ebml_element Base;
34     uint32_t CRC;
35 };
36 
37 /* Compute the CRC 32 IEEE Little Endian */
38 
39 const uint32_t CRC32_NEGL = 0xffffffffL;
40 const uint32_t m_tab[] = {
41 #ifdef IS_BIG_ENDIAN
42 	0x00000000L, 0x96300777L, 0x2c610eeeL, 0xba510999L, 0x19c46d07L,
43 	0x8ff46a70L, 0x35a563e9L, 0xa395649eL, 0x3288db0eL, 0xa4b8dc79L,
44 	0x1ee9d5e0L, 0x88d9d297L, 0x2b4cb609L, 0xbd7cb17eL, 0x072db8e7L,
45 	0x911dbf90L, 0x6410b71dL, 0xf220b06aL, 0x4871b9f3L, 0xde41be84L,
46 	0x7dd4da1aL, 0xebe4dd6dL, 0x51b5d4f4L, 0xc785d383L, 0x56986c13L,
47 	0xc0a86b64L, 0x7af962fdL, 0xecc9658aL, 0x4f5c0114L, 0xd96c0663L,
48 	0x633d0ffaL, 0xf50d088dL, 0xc8206e3bL, 0x5e10694cL, 0xe44160d5L,
49 	0x727167a2L, 0xd1e4033cL, 0x47d4044bL, 0xfd850dd2L, 0x6bb50aa5L,
50 	0xfaa8b535L, 0x6c98b242L, 0xd6c9bbdbL, 0x40f9bcacL, 0xe36cd832L,
51 	0x755cdf45L, 0xcf0dd6dcL, 0x593dd1abL, 0xac30d926L, 0x3a00de51L,
52 	0x8051d7c8L, 0x1661d0bfL, 0xb5f4b421L, 0x23c4b356L, 0x9995bacfL,
53 	0x0fa5bdb8L, 0x9eb80228L, 0x0888055fL, 0xb2d90cc6L, 0x24e90bb1L,
54 	0x877c6f2fL, 0x114c6858L, 0xab1d61c1L, 0x3d2d66b6L, 0x9041dc76L,
55 	0x0671db01L, 0xbc20d298L, 0x2a10d5efL, 0x8985b171L, 0x1fb5b606L,
56 	0xa5e4bf9fL, 0x33d4b8e8L, 0xa2c90778L, 0x34f9000fL, 0x8ea80996L,
57 	0x18980ee1L, 0xbb0d6a7fL, 0x2d3d6d08L, 0x976c6491L, 0x015c63e6L,
58 	0xf4516b6bL, 0x62616c1cL, 0xd8306585L, 0x4e0062f2L, 0xed95066cL,
59 	0x7ba5011bL, 0xc1f40882L, 0x57c40ff5L, 0xc6d9b065L, 0x50e9b712L,
60 	0xeab8be8bL, 0x7c88b9fcL, 0xdf1ddd62L, 0x492dda15L, 0xf37cd38cL,
61 	0x654cd4fbL, 0x5861b24dL, 0xce51b53aL, 0x7400bca3L, 0xe230bbd4L,
62 	0x41a5df4aL, 0xd795d83dL, 0x6dc4d1a4L, 0xfbf4d6d3L, 0x6ae96943L,
63 	0xfcd96e34L, 0x468867adL, 0xd0b860daL, 0x732d0444L, 0xe51d0333L,
64 	0x5f4c0aaaL, 0xc97c0dddL, 0x3c710550L, 0xaa410227L, 0x10100bbeL,
65 	0x86200cc9L, 0x25b56857L, 0xb3856f20L, 0x09d466b9L, 0x9fe461ceL,
66 	0x0ef9de5eL, 0x98c9d929L, 0x2298d0b0L, 0xb4a8d7c7L, 0x173db359L,
67 	0x810db42eL, 0x3b5cbdb7L, 0xad6cbac0L, 0x2083b8edL, 0xb6b3bf9aL,
68 	0x0ce2b603L, 0x9ad2b174L, 0x3947d5eaL, 0xaf77d29dL, 0x1526db04L,
69 	0x8316dc73L, 0x120b63e3L, 0x843b6494L, 0x3e6a6d0dL, 0xa85a6a7aL,
70 	0x0bcf0ee4L, 0x9dff0993L, 0x27ae000aL, 0xb19e077dL, 0x44930ff0L,
71 	0xd2a30887L, 0x68f2011eL, 0xfec20669L, 0x5d5762f7L, 0xcb676580L,
72 	0x71366c19L, 0xe7066b6eL, 0x761bd4feL, 0xe02bd389L, 0x5a7ada10L,
73 	0xcc4add67L, 0x6fdfb9f9L, 0xf9efbe8eL, 0x43beb717L, 0xd58eb060L,
74 	0xe8a3d6d6L, 0x7e93d1a1L, 0xc4c2d838L, 0x52f2df4fL, 0xf167bbd1L,
75 	0x6757bca6L, 0xdd06b53fL, 0x4b36b248L, 0xda2b0dd8L, 0x4c1b0aafL,
76 	0xf64a0336L, 0x607a0441L, 0xc3ef60dfL, 0x55df67a8L, 0xef8e6e31L,
77 	0x79be6946L, 0x8cb361cbL, 0x1a8366bcL, 0xa0d26f25L, 0x36e26852L,
78 	0x95770cccL, 0x03470bbbL, 0xb9160222L, 0x2f260555L, 0xbe3bbac5L,
79 	0x280bbdb2L, 0x925ab42bL, 0x046ab35cL, 0xa7ffd7c2L, 0x31cfd0b5L,
80 	0x8b9ed92cL, 0x1daede5bL, 0xb0c2649bL, 0x26f263ecL, 0x9ca36a75L,
81 	0x0a936d02L, 0xa906099cL, 0x3f360eebL, 0x85670772L, 0x13570005L,
82 	0x824abf95L, 0x147ab8e2L, 0xae2bb17bL, 0x381bb60cL, 0x9b8ed292L,
83 	0x0dbed5e5L, 0xb7efdc7cL, 0x21dfdb0bL, 0xd4d2d386L, 0x42e2d4f1L,
84 	0xf8b3dd68L, 0x6e83da1fL, 0xcd16be81L, 0x5b26b9f6L, 0xe177b06fL,
85 	0x7747b718L, 0xe65a0888L, 0x706a0fffL, 0xca3b0666L, 0x5c0b0111L,
86 	0xff9e658fL, 0x69ae62f8L, 0xd3ff6b61L, 0x45cf6c16L, 0x78e20aa0L,
87 	0xeed20dd7L, 0x5483044eL, 0xc2b30339L, 0x612667a7L, 0xf71660d0L,
88 	0x4d476949L, 0xdb776e3eL, 0x4a6ad1aeL, 0xdc5ad6d9L, 0x660bdf40L,
89 	0xf03bd837L, 0x53aebca9L, 0xc59ebbdeL, 0x7fcfb247L, 0xe9ffb530L,
90 	0x1cf2bdbdL, 0x8ac2bacaL, 0x3093b353L, 0xa6a3b424L, 0x0536d0baL,
91 	0x9306d7cdL, 0x2957de54L, 0xbf67d923L, 0x2e7a66b3L, 0xb84a61c4L,
92 	0x021b685dL, 0x942b6f2aL, 0x37be0bb4L, 0xa18e0cc3L, 0x1bdf055aL,
93 	0x8def022dL
94 #else
95 	0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
96 	0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
97 	0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
98 	0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
99 	0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
100 	0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
101 	0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
102 	0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
103 	0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
104 	0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
105 	0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
106 	0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
107 	0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
108 	0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
109 	0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
110 	0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
111 	0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
112 	0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
113 	0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
114 	0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
115 	0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
116 	0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
117 	0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
118 	0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
119 	0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
120 	0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
121 	0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
122 	0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
123 	0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
124 	0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
125 	0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
126 	0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
127 	0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
128 	0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
129 	0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
130 	0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
131 	0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
132 	0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
133 	0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
134 	0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
135 	0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
136 	0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
137 	0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
138 	0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
139 	0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
140 	0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
141 	0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
142 	0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
143 	0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
144 	0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
145 	0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
146 	0x2d02ef8dL
147 #endif
148 };
149 
150 #ifdef IS_BIG_ENDIAN
151 # define CRC32_INDEX(c) (c >> 24)
152 # define CRC32_SHIFTED(c) (c << 8)
153 #else
154 # define CRC32_INDEX(c) (c & 0xff)
155 # define CRC32_SHIFTED(c) (c >> 8)
156 #endif
157 
ValidateSize(const ebml_element * p)158 static bool_t ValidateSize(const ebml_element *p)
159 {
160     return EBML_ElementIsFiniteSize(p) && (p->DataSize == 4);
161 }
162 
ReadData(ebml_crc * Element,stream * Input,const ebml_parser_context * ParserContext,bool_t AllowDummyElt,int Scope,size_t DepthCheckCRC)163 static err_t ReadData(ebml_crc *Element, stream *Input, const ebml_parser_context *ParserContext, bool_t AllowDummyElt, int Scope, size_t DepthCheckCRC)
164 {
165     err_t Result;
166     uint32_t CRCbuffer;
167     Result = Stream_Read(Input,&CRCbuffer,4,NULL);
168     if (Result == ERR_NONE)
169     {
170         Element->CRC = LOAD32LE(&CRCbuffer);
171         Element->Base.bValueIsSet = 1;
172     }
173     return Result;
174 }
175 
176 #if defined(CONFIG_EBML_WRITING)
RenderData(ebml_crc * Element,stream * Output,bool_t bForceWithoutMandatory,bool_t bWithDefault,filepos_t * Rendered)177 static err_t RenderData(ebml_crc *Element, stream *Output, bool_t bForceWithoutMandatory, bool_t bWithDefault, filepos_t *Rendered)
178 {
179     err_t Result;
180     size_t Written = 0;
181     uint8_t Buf[4];
182     STORE32LE(Buf,Element->CRC);
183     Result = Stream_Write(Output, Buf, 4, &Written);
184     if (Rendered)
185         *Rendered = Written;
186     return Result;
187 }
188 #endif
189 
Copy(const ebml_crc * Element,const void * Cookie)190 static ebml_crc *Copy(const ebml_crc *Element, const void *Cookie)
191 {
192     ebml_crc *Result = (ebml_crc*)EBML_ElementCreate(Element,Element->Base.Context,0,Cookie);
193     if (Result)
194     {
195         Result->CRC = Element->CRC;
196         Result->Base.bValueIsSet = Element->Base.bValueIsSet;
197         Result->Base.DataSize = Element->Base.DataSize;
198         Result->Base.ElementPosition = Element->Base.ElementPosition;
199         Result->Base.SizeLength = Element->Base.SizeLength;
200         Result->Base.SizePosition = Element->Base.SizePosition;
201         Result->Base.bNeedDataSizeUpdate = Element->Base.bNeedDataSizeUpdate;
202     }
203     return Result;
204 }
205 
IsDefaultValue(const ebml_element * Element)206 static bool_t IsDefaultValue(const ebml_element *Element)
207 {
208     return 0; // CRC has no default value
209 }
210 
Create(ebml_crc * Element)211 static err_t Create(ebml_crc *Element)
212 {
213     Element->CRC = CRC32_NEGL;
214     Element->Base.bNeedDataSizeUpdate = 0;
215     Element->Base.DataSize = 4;
216     return ERR_NONE;
217 }
218 
META_START(EBMLCRC_Class,EBML_CRC_CLASS)219 META_START(EBMLCRC_Class,EBML_CRC_CLASS)
220 META_CLASS(SIZE,sizeof(ebml_crc))
221 META_CLASS(CREATE,Create)
222 META_VMT(TYPE_FUNC,ebml_element_vmt,ValidateSize,ValidateSize)
223 META_VMT(TYPE_FUNC,ebml_element_vmt,ReadData,ReadData)
224 META_VMT(TYPE_FUNC,ebml_element_vmt,Copy,Copy)
225 META_VMT(TYPE_FUNC,ebml_element_vmt,IsDefaultValue,IsDefaultValue)
226 #if defined(CONFIG_EBML_WRITING)
227 META_VMT(TYPE_FUNC,ebml_element_vmt,RenderData,RenderData)
228 #endif
229 META_END(EBML_ELEMENT_CLASS)
230 
231 bool_t EBML_CRCMatches(ebml_crc *CRC, const uint8_t *Buf, size_t Size)
232 {
233     uint32_t testCRC = CRC32_NEGL;
234 
235     assert(CRC->Base.bValueIsSet);
236 
237 /* TODO: needed for non aligned memory ?
238 	for(; !aligned(Buf) && Size > 0; Size--)
239 		testCRC = m_tab[CRC32_INDEX(testCRC) ^ *Buf++] ^ CRC32_SHIFTED(testCRC);
240 */
241 	while (Size >= 4)
242 	{
243 		testCRC ^= *(const uint32_t *)Buf;
244 		testCRC = m_tab[CRC32_INDEX(testCRC)] ^ CRC32_SHIFTED(testCRC);
245 		testCRC = m_tab[CRC32_INDEX(testCRC)] ^ CRC32_SHIFTED(testCRC);
246 		testCRC = m_tab[CRC32_INDEX(testCRC)] ^ CRC32_SHIFTED(testCRC);
247 		testCRC = m_tab[CRC32_INDEX(testCRC)] ^ CRC32_SHIFTED(testCRC);
248 		Size -= 4;
249 		Buf += 4;
250 	}
251 
252 	while (Size--)
253 		testCRC = m_tab[CRC32_INDEX(testCRC) ^ *Buf++] ^ CRC32_SHIFTED(testCRC);
254 
255 	testCRC ^= CRC32_NEGL;
256 
257     return (CRC->CRC == testCRC);
258 }
259 
EBML_CRCAddBuffer(ebml_crc * CRC,const uint8_t * Buf,size_t Size)260 void EBML_CRCAddBuffer(ebml_crc *CRC, const uint8_t *Buf, size_t Size)
261 {
262 	while (Size >= 4)
263 	{
264 		CRC->CRC ^= *(const uint32_t *)Buf;
265 		CRC->CRC = m_tab[CRC32_INDEX(CRC->CRC)] ^ CRC32_SHIFTED(CRC->CRC);
266 		CRC->CRC = m_tab[CRC32_INDEX(CRC->CRC)] ^ CRC32_SHIFTED(CRC->CRC);
267 		CRC->CRC = m_tab[CRC32_INDEX(CRC->CRC)] ^ CRC32_SHIFTED(CRC->CRC);
268 		CRC->CRC = m_tab[CRC32_INDEX(CRC->CRC)] ^ CRC32_SHIFTED(CRC->CRC);
269 		Size -= 4;
270 		Buf += 4;
271 	}
272 
273 	while (Size--)
274 		CRC->CRC = m_tab[CRC32_INDEX(CRC->CRC) ^ *Buf++] ^ CRC32_SHIFTED(CRC->CRC);
275 }
276 
EBML_CRCFinalize(ebml_crc * CRC)277 void EBML_CRCFinalize(ebml_crc *CRC)
278 {
279 	CRC->CRC ^= CRC32_NEGL;
280     CRC->Base.DataSize = 4;
281     CRC->Base.bValueIsSet = 1;
282 }
283