1 /*---------------------------------------------------------------------------*
2   Project:  RevolutionSDK Extensions - Network base library
3   File:     NETDigest.h
4 
5   Copyright (C) 2006 Nintendo. All Rights Reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law. They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Log: NETDigest.h,v $
14   Revision 1.7  2008/04/28 06:57:07  hirose_kazuki
15   Added SHA-256.
16 
17   Revision 1.6  2007/10/31 00:09:00  seiki_masashi
18   Changed the types of the arguments of the NETCalcHMAC* functions.
19 
20   Revision 1.5  2006/10/17 08:11:07  yosizaki
21   Fixed NETCalcHMAC
22 
23   Revision 1.4  2006/10/14 01:44:07  yosizaki
24   Reorganized the SHA1 and HMAC API.
25 
26   Revision 1.3  2006/10/11 07:27:04  yosizaki
27   Added support for settings other than RVL_OS.
28 
29   Revision 1.2  2006/10/11 04:28:26  yosizaki
30   Added functions for NETHMACContext.
31 
32   Revision 1.1  2006/09/08 12:00:22  seiki_masashi
33   Split net.h into multiple header files
34 
35   $NoKeywords: $
36  *---------------------------------------------------------------------------*/
37 
38 /*---------------------------------------------------------------------------*
39     Header file for network base API.
40  *---------------------------------------------------------------------------*/
41 
42 #ifndef __NETDIGEST_H__
43 #define __NETDIGEST_H__
44 
45 #ifdef RVL_OS
46 #include <revolution/os.h>
47 #endif // RVL_OS
48 
49 #ifdef __cplusplus
50 extern "C" {
51 #endif
52 /*---------------------------------------------------------------------------*/
53 
54 #define NET_MD5_DIGEST_SIZE     16
55 #define NET_SHA1_DIGEST_SIZE    20
56 #define NET_SHA256_DIGEST_SIZE  32
57 
58 #define NET_MD5_BLOCK_SIZE      64
59 #define NET_SHA1_BLOCK_SIZE     64UL
60 #define NET_SHA256_BLOCK_SIZE   64UL
61 
62 /*---------------------------------------------------------------------------*/
63 
64 u16 NETCalcCRC16( const void* datap, u32 size );
65 u32 NETCalcCRC32( const void* datap, u32 size );
66 
67 /*---------------------------------------------------------------------------*/
68 
NETSwapBytes16(u16 val)69 inline static u16 NETSwapBytes16( u16 val )
70 {
71     return (u16)( (((val) >> 8UL) & 0x00FFUL) |
72                   (((val) << 8UL) & 0xFF00UL) );
73 }
74 
NETSwapBytes32(u32 val)75 inline static u32 NETSwapBytes32( u32 val )
76 {
77     return (u32)( (((val) >> 24UL) & 0x000000FFUL) |
78                   (((val) >>  8UL) & 0x0000FF00UL) |
79                   (((val) <<  8UL) & 0x00FF0000UL) |
80                   (((val) << 24UL) & 0xFF000000UL) );
81 }
82 
83 #ifdef RVL_OS
NETReadSwappedBytes16(const u16 * src)84 inline static u16 NETReadSwappedBytes16( const u16* src )
85 {
86     return (u16)__lhbrx((void*)(src), 0);
87 }
88 
NETReadSwappedBytes32(const u32 * src)89 inline static u32 NETReadSwappedBytes32( const u32* src )
90 {
91     return (u32)__lwbrx((void*)(src), 0);
92 }
93 
NETWriteSwappedBytes16(u16 * dst,u16 val)94 inline static void NETWriteSwappedBytes16( u16* dst, u16 val )
95 {
96     __sthbrx(val, (void*)(dst), 0);
97 }
98 
NETWriteSwappedBytes32(u32 * dst,u32 val)99 inline static void NETWriteSwappedBytes32( u32* dst, u32 val )
100 {
101     __stwbrx(val, (void*)(dst), 0);
102 }
103 #else // RVL_OS
NETReadSwappedBytes16(const u16 * src)104 inline static u16 NETReadSwappedBytes16( const u16* src )
105 {
106     return NETSwapBytes16(*src);
107 }
108 
NETReadSwappedBytes32(const u32 * src)109 inline static u32 NETReadSwappedBytes32( const u32* src )
110 {
111     return NETSwapBytes32(*src);
112 }
113 
NETWriteSwappedBytes16(u16 * dst,u16 val)114 inline static void NETWriteSwappedBytes16( u16* dst, u16 val )
115 {
116     *dst = NETSwapBytes16(val);
117 }
118 
NETWriteSwappedBytes32(u32 * dst,u32 val)119 inline static void NETWriteSwappedBytes32( u32* dst, u32 val )
120 {
121     *dst = NETSwapBytes32(val);
122 }
123 #endif // RVL_OS
124 
125 /*---------------------------------------------------------------------------*/
126 
127 typedef struct NETHashInterface
128 {
129     u32     hashLength;
130     u32     blockLength;
131     u32     workLength;
132     void   *context;
133     void (*Init)(void *context);
134     void (*Update)(void *context, const void *message, u32 length);
135     void (*GetDigest)(void *context, void *digest);
136 }
137 NETHashInterface;
138 
139 #define NET_HASH_INTERFACE_MD5      NETGetMD5Interface()
140 #define NET_HASH_INTERFACE_SHA1     NETGetSHA1Interface()
141 #define NET_HASH_INTERFACE_SHA256   NETGetSHA256Interface()
142 
143 /*---------------------------------------------------------------------------*/
144 
145 typedef struct NETMD5Context
146 {
147     union
148     {
149         struct
150         {
151             unsigned long a, b, c, d;
152         };
153         unsigned long state[4];
154     };
155     unsigned long long length;
156     union
157     {
158         unsigned long buffer32[16];
159         unsigned char buffer8[64];
160     };
161 } NETMD5Context;
162 
163 void NETMD5Init(NETMD5Context* context);
164 void NETMD5Update(NETMD5Context* context, const void* input, u32 length);
165 void NETMD5GetDigest(NETMD5Context* context, void* digest);
166 const NETHashInterface* NETGetMD5Interface(void);
167 
NETCalcMD5(void * digest,const void * input,u32 length)168 inline static void NETCalcMD5(void* digest, const void* input, u32 length)
169 {
170     NETMD5Context context;
171 
172     NETMD5Init(&context);
173     NETMD5Update(&context, input, length);
174     NETMD5GetDigest(&context, digest);
175 }
176 
177 /*---------------------------------------------------------------------------*/
178 
179 typedef struct NETSHA1Context
180 {
181     u32     h[5];                       /* H0,H1,H2,H3,H4 */
182     u8      block[NET_SHA1_BLOCK_SIZE]; /* current message block */
183     u32     pool;                       /* message length in 'block' */
184     u32     blocks_low;                 /* total blocks (in bytes) */
185     u32     blocks_high;
186 }
187 NETSHA1Context;
188 
189 void NETSHA1Init(NETSHA1Context* context);
190 void NETSHA1Update(NETSHA1Context* context, const void* input, u32 length);
191 void NETSHA1Fill(NETSHA1Context* context, u8 input, u32 length);
192 void NETSHA1GetDigest(NETSHA1Context* context, void* digest);
193 const NETHashInterface* NETGetSHA1Interface(void);
194 
NETCalcSHA1(void * digest,const void * input,u32 length)195 inline static void NETCalcSHA1(void* digest, const void* input, u32 length)
196 {
197     NETSHA1Context context;
198 
199     NETSHA1Init(&context);
200     NETSHA1Update(&context, input, length);
201     NETSHA1GetDigest(&context, digest);
202 }
203 
204 /*---------------------------------------------------------------------------*/
205 
206 typedef struct NETSHA256Context
207 {
208     u32     h[8];                           /* H0,H1,H2,H3,H4,H5,H6,H7 */
209     u8      block[NET_SHA256_BLOCK_SIZE];   /* current message block */
210     u32     pool;                           /* message length in 'block' */
211     u32     blocks_low;                     /* total blocks (in bytes) */
212     u32     blocks_high;
213 }
214 NETSHA256Context;
215 
216 void NETSHA256Init(NETSHA256Context* context);
217 void NETSHA256Update(NETSHA256Context* context, const void* input, u32 length);
218 void NETSHA256Fill(NETSHA256Context* context, u8 input, u32 length);
219 void NETSHA256GetDigest(NETSHA256Context* context, void* digest);
220 const NETHashInterface* NETGetSHA256Interface(void);
221 
NETCalcSHA256(void * digest,const void * input,u32 length)222 inline static void NETCalcSHA256(void* digest, const void* input, u32 length)
223 {
224     NETSHA256Context context;
225 
226     NETSHA256Init(&context);
227     NETSHA256Update(&context, input, length);
228     NETSHA256GetDigest(&context, digest);
229 }
230 
231 /*---------------------------------------------------------------------------*/
232 
233 typedef struct NETHMACContext
234 {
235     NETHashInterface    hashInterface[1];
236     u32                 keyLength;
237     union
238     {
239         NETMD5Context       md5;
240         NETSHA1Context      sha1;
241         NETSHA256Context    sha256;
242         u8                  buffer[1];
243     }
244     hashContext;
245     union
246     {
247         u8                  md5[NET_MD5_BLOCK_SIZE];
248         u8                  sha1[NET_SHA1_BLOCK_SIZE];
249         u8                  sha256[NET_SHA256_BLOCK_SIZE];
250         u8                  buffer[1];
251     }
252     key;
253     u8                  padding[8];
254 }
255 NETHMACContext;
256 
257 void NETHMACInit(NETHMACContext* context,
258                  const NETHashInterface *hashInterface,
259                  const void *key, u32 keyLength);
260 void NETHMACUpdate(NETHMACContext* context, const void *message, u32 length);
261 void NETHMACGetDigest(NETHMACContext* context, void *digest);
262 
NETCalcHMACMD5(void * digest,const void * data,u32 dataLength,const void * key,u32 keyLength)263 inline static void NETCalcHMACMD5(void *digest, const void *data, u32 dataLength, const void *key, u32 keyLength)
264 {
265     NETHMACContext hmac[1];
266     NETHMACInit(hmac, NET_HASH_INTERFACE_MD5, key, keyLength);
267     NETHMACUpdate(hmac, data, dataLength);
268     NETHMACGetDigest(hmac, digest);
269 }
270 
NETCalcHMACSHA1(void * digest,const void * data,u32 dataLength,const void * key,u32 keyLength)271 inline static void NETCalcHMACSHA1(void *digest, const void *data, u32 dataLength, const void *key, u32 keyLength)
272 {
273     NETHMACContext hmac[1];
274     NETHMACInit(hmac, NET_HASH_INTERFACE_SHA1, key, keyLength);
275     NETHMACUpdate(hmac, data, dataLength);
276     NETHMACGetDigest(hmac, digest);
277 }
278 
NETCalcHMACSHA256(void * digest,const void * data,u32 dataLength,const void * key,u32 keyLength)279 inline static void NETCalcHMACSHA256(void *digest, const void *data, u32 dataLength, const void *key, u32 keyLength)
280 {
281     NETHMACContext hmac[1];
282     NETHMACInit(hmac, NET_HASH_INTERFACE_SHA256, key, keyLength);
283     NETHMACUpdate(hmac, data, dataLength);
284     NETHMACGetDigest(hmac, digest);
285 }
286 
287 
288 /*---------------------------------------------------------------------------*/
289 
290 #ifdef __cplusplus
291 }
292 #endif
293 
294 #endif // __NETDIGEST_H__
295 
296