/*---------------------------------------------------------------------------* Project: RevolutionSDK Extensions - Network base library File: NETDigest.h Copyright (C) 2006 Nintendo. All Rights Reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Log: NETDigest.h,v $ Revision 1.7 2008/04/28 06:57:07 hirose_kazuki Added SHA-256. Revision 1.6 2007/10/31 00:09:00 seiki_masashi Changed the types of the arguments of the NETCalcHMAC* functions. Revision 1.5 2006/10/17 08:11:07 yosizaki Fixed NETCalcHMAC Revision 1.4 2006/10/14 01:44:07 yosizaki Reorganized the SHA1 and HMAC API. Revision 1.3 2006/10/11 07:27:04 yosizaki Added support for settings other than RVL_OS. Revision 1.2 2006/10/11 04:28:26 yosizaki Added functions for NETHMACContext. Revision 1.1 2006/09/08 12:00:22 seiki_masashi Split net.h into multiple header files $NoKeywords: $ *---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------* Header file for network base API. *---------------------------------------------------------------------------*/ #ifndef __NETDIGEST_H__ #define __NETDIGEST_H__ #ifdef RVL_OS #include #endif // RVL_OS #ifdef __cplusplus extern "C" { #endif /*---------------------------------------------------------------------------*/ #define NET_MD5_DIGEST_SIZE 16 #define NET_SHA1_DIGEST_SIZE 20 #define NET_SHA256_DIGEST_SIZE 32 #define NET_MD5_BLOCK_SIZE 64 #define NET_SHA1_BLOCK_SIZE 64UL #define NET_SHA256_BLOCK_SIZE 64UL /*---------------------------------------------------------------------------*/ u16 NETCalcCRC16( const void* datap, u32 size ); u32 NETCalcCRC32( const void* datap, u32 size ); /*---------------------------------------------------------------------------*/ inline static u16 NETSwapBytes16( u16 val ) { return (u16)( (((val) >> 8UL) & 0x00FFUL) | (((val) << 8UL) & 0xFF00UL) ); } inline static u32 NETSwapBytes32( u32 val ) { return (u32)( (((val) >> 24UL) & 0x000000FFUL) | (((val) >> 8UL) & 0x0000FF00UL) | (((val) << 8UL) & 0x00FF0000UL) | (((val) << 24UL) & 0xFF000000UL) ); } #ifdef RVL_OS inline static u16 NETReadSwappedBytes16( const u16* src ) { return (u16)__lhbrx((void*)(src), 0); } inline static u32 NETReadSwappedBytes32( const u32* src ) { return (u32)__lwbrx((void*)(src), 0); } inline static void NETWriteSwappedBytes16( u16* dst, u16 val ) { __sthbrx(val, (void*)(dst), 0); } inline static void NETWriteSwappedBytes32( u32* dst, u32 val ) { __stwbrx(val, (void*)(dst), 0); } #else // RVL_OS inline static u16 NETReadSwappedBytes16( const u16* src ) { return NETSwapBytes16(*src); } inline static u32 NETReadSwappedBytes32( const u32* src ) { return NETSwapBytes32(*src); } inline static void NETWriteSwappedBytes16( u16* dst, u16 val ) { *dst = NETSwapBytes16(val); } inline static void NETWriteSwappedBytes32( u32* dst, u32 val ) { *dst = NETSwapBytes32(val); } #endif // RVL_OS /*---------------------------------------------------------------------------*/ typedef struct NETHashInterface { u32 hashLength; u32 blockLength; u32 workLength; void *context; void (*Init)(void *context); void (*Update)(void *context, const void *message, u32 length); void (*GetDigest)(void *context, void *digest); } NETHashInterface; #define NET_HASH_INTERFACE_MD5 NETGetMD5Interface() #define NET_HASH_INTERFACE_SHA1 NETGetSHA1Interface() #define NET_HASH_INTERFACE_SHA256 NETGetSHA256Interface() /*---------------------------------------------------------------------------*/ typedef struct NETMD5Context { union { struct { unsigned long a, b, c, d; }; unsigned long state[4]; }; unsigned long long length; union { unsigned long buffer32[16]; unsigned char buffer8[64]; }; } NETMD5Context; void NETMD5Init(NETMD5Context* context); void NETMD5Update(NETMD5Context* context, const void* input, u32 length); void NETMD5GetDigest(NETMD5Context* context, void* digest); const NETHashInterface* NETGetMD5Interface(void); inline static void NETCalcMD5(void* digest, const void* input, u32 length) { NETMD5Context context; NETMD5Init(&context); NETMD5Update(&context, input, length); NETMD5GetDigest(&context, digest); } /*---------------------------------------------------------------------------*/ typedef struct NETSHA1Context { u32 h[5]; /* H0,H1,H2,H3,H4 */ u8 block[NET_SHA1_BLOCK_SIZE]; /* current message block */ u32 pool; /* message length in 'block' */ u32 blocks_low; /* total blocks (in bytes) */ u32 blocks_high; } NETSHA1Context; void NETSHA1Init(NETSHA1Context* context); void NETSHA1Update(NETSHA1Context* context, const void* input, u32 length); void NETSHA1Fill(NETSHA1Context* context, u8 input, u32 length); void NETSHA1GetDigest(NETSHA1Context* context, void* digest); const NETHashInterface* NETGetSHA1Interface(void); inline static void NETCalcSHA1(void* digest, const void* input, u32 length) { NETSHA1Context context; NETSHA1Init(&context); NETSHA1Update(&context, input, length); NETSHA1GetDigest(&context, digest); } /*---------------------------------------------------------------------------*/ typedef struct NETSHA256Context { u32 h[8]; /* H0,H1,H2,H3,H4,H5,H6,H7 */ u8 block[NET_SHA256_BLOCK_SIZE]; /* current message block */ u32 pool; /* message length in 'block' */ u32 blocks_low; /* total blocks (in bytes) */ u32 blocks_high; } NETSHA256Context; void NETSHA256Init(NETSHA256Context* context); void NETSHA256Update(NETSHA256Context* context, const void* input, u32 length); void NETSHA256Fill(NETSHA256Context* context, u8 input, u32 length); void NETSHA256GetDigest(NETSHA256Context* context, void* digest); const NETHashInterface* NETGetSHA256Interface(void); inline static void NETCalcSHA256(void* digest, const void* input, u32 length) { NETSHA256Context context; NETSHA256Init(&context); NETSHA256Update(&context, input, length); NETSHA256GetDigest(&context, digest); } /*---------------------------------------------------------------------------*/ typedef struct NETHMACContext { NETHashInterface hashInterface[1]; u32 keyLength; union { NETMD5Context md5; NETSHA1Context sha1; NETSHA256Context sha256; u8 buffer[1]; } hashContext; union { u8 md5[NET_MD5_BLOCK_SIZE]; u8 sha1[NET_SHA1_BLOCK_SIZE]; u8 sha256[NET_SHA256_BLOCK_SIZE]; u8 buffer[1]; } key; u8 padding[8]; } NETHMACContext; void NETHMACInit(NETHMACContext* context, const NETHashInterface *hashInterface, const void *key, u32 keyLength); void NETHMACUpdate(NETHMACContext* context, const void *message, u32 length); void NETHMACGetDigest(NETHMACContext* context, void *digest); inline static void NETCalcHMACMD5(void *digest, const void *data, u32 dataLength, const void *key, u32 keyLength) { NETHMACContext hmac[1]; NETHMACInit(hmac, NET_HASH_INTERFACE_MD5, key, keyLength); NETHMACUpdate(hmac, data, dataLength); NETHMACGetDigest(hmac, digest); } inline static void NETCalcHMACSHA1(void *digest, const void *data, u32 dataLength, const void *key, u32 keyLength) { NETHMACContext hmac[1]; NETHMACInit(hmac, NET_HASH_INTERFACE_SHA1, key, keyLength); NETHMACUpdate(hmac, data, dataLength); NETHMACGetDigest(hmac, digest); } inline static void NETCalcHMACSHA256(void *digest, const void *data, u32 dataLength, const void *key, u32 keyLength) { NETHMACContext hmac[1]; NETHMACInit(hmac, NET_HASH_INTERFACE_SHA256, key, keyLength); NETHMACUpdate(hmac, data, dataLength); NETHMACGetDigest(hmac, digest); } /*---------------------------------------------------------------------------*/ #ifdef __cplusplus } #endif #endif // __NETDIGEST_H__