8 #ifndef MI_NEURAYLIB_ILIBRARY_AUTHENTICATION_H
9 #define MI_NEURAYLIB_ILIBRARY_AUTHENTICATION_H
15 #ifdef MI_PLATFORM_WINDOWS
16 #include <mi/base/miwindows.h>
33 class ILibrary_authenticator :
public
41 mi::base::Interface_declare<0x5a7d010a,0x2a65,0x43da,0x92,0xf2,0xcd,0xd9,0xc8,0x4b,0x10,0xd2>
65 const INeuray* library,
66 const char* vendor_key,
Sint32 vendor_key_length,
67 const char* secret_key,
Sint32 secret_key_length);
84 virtual Sint32 get_challenge(
char* buffer,
Sint32 buffer_length) = 0;
100 virtual void submit_challenge_response(
101 const char* response,
Sint32 response_length,
102 const char* vendor_key,
Sint32 vendor_key_length,
103 const char* salt,
Sint32 salt_length) = 0;
111 static void generate_nounce(
char* out_buffer);
120 static void calculate_response(
121 const char* salt,
const char* challenge,
122 const char* secret_key,
Sint32 secret_key_length,
char* out_response);
129 static void sha256(
const char* input,
int input_length,
char* out_buffer);
134 const char* vendor_key,
Sint32 vendor_key_length,
135 const char* secret_key,
Sint32 secret_key_length)
146 memset( &challenge[0], 0, 32);
147 if( authenticator->get_challenge( challenge, static_cast<Sint32>(
sizeof( challenge)))
148 >
static_cast<Sint32>(
sizeof( challenge)))
152 detail::generate_nounce( salt);
155 detail::calculate_response( salt, challenge, secret_key, secret_key_length, response);
157 authenticator->submit_challenge_response(
158 response, static_cast<Sint32>(
sizeof( response)), vendor_key, vendor_key_length,
159 salt, static_cast<Sint32>(
sizeof( salt)));
166 void calculate_response(
167 const char* salt,
const char* challenge,
168 const char* secret_key,
Sint32 secret_key_length,
char* out_response)
170 if( (secret_key_length < 0) || (secret_key_length > 1024*10))
173 int total_len = 32 + 32 + secret_key_length;
174 char* buffer =
new char[total_len];
175 memcpy( buffer, salt, 32);
176 memcpy( buffer + 32, challenge, 32);
177 memcpy( buffer + 64, secret_key, secret_key_length);
178 sha256( buffer, total_len, out_response);
182 void generate_nounce(
char* out_buffer)
187 #ifdef MI_PLATFORM_WINDOWS
188 srand( GetTickCount());
190 QueryPerformanceCounter( &tmp);
191 number += tmp.QuadPart + GetCurrentProcessId() + GetTickCount();
193 srand( static_cast<unsigned>( time( 0)));
195 gettimeofday( &tv, 0);
196 number += tv.tv_sec + tv.tv_usec;
200 memcpy( buf, &r,
sizeof(
Uint32));
201 memcpy( buf +
sizeof(
Uint32), &number,
sizeof(
Uint64));
205 sha256( const_cast<const char*>( buf), static_cast<Sint32>(
sizeof( buf)), out_buffer);
210 static const Uint32 sha256_constants[] = {
211 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
212 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
213 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
214 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
215 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
216 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
217 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
218 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
224 return ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) |
225 (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24));
231 return (( x >> y) | (x << (32-y)));
234 void sha256(
const char* input,
int input_length,
char* out_buffer)
236 if( (input_length <= 0) || (input == 0) || (out_buffer == 0))
240 Uint32 state[] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
241 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
244 int k = 448 - (input_length * 8 + 1) % 512;
249 for(
int chunk = 0; k != 0; ++chunk) {
253 int to_copy = input_length - pos;
254 to_copy = to_copy > 64 ? 64 : to_copy;
256 memcpy( ptr, input + pos, to_copy);
261 if( pos == input_length) {
263 if( (k > 0) && (pos % 64 < 64) && (pos/64 == chunk))
264 ptr[pos%64] |=
static_cast<Uint8>( 0x80);
266 if( (pos*8 + 1 + k) - (chunk*512) <= 448) {
267 Uint64 value = input_length * 8;
268 ptr =
reinterpret_cast<Uint8*
>(&W[14]);
269 ptr[0] =
static_cast<Uint8>((value >> 56) & 0xff);
270 ptr[1] =
static_cast<Uint8>((value >> 48) & 0xff);
271 ptr[2] =
static_cast<Uint8>((value >> 40) & 0xff);
272 ptr[3] =
static_cast<Uint8>((value >> 32) & 0xff);
273 ptr[4] =
static_cast<Uint8>((value >> 24) & 0xff);
274 ptr[5] =
static_cast<Uint8>((value >> 16) & 0xff);
275 ptr[6] =
static_cast<Uint8>((value >> 8) & 0xff);
276 ptr[7] =
static_cast<Uint8>( value & 0xff);
282 for(
int i = 0; i < 16; ++i)
283 W[i] = flip32( W[i]);
286 for(
Uint32 i = 16; i < 64; ++i) {
287 Uint32 s0 = rightrotate( W[i-15], 7) ^ rightrotate( W[i-15], 18) ^ (W[i-15] >> 3);
288 Uint32 s1 = rightrotate( W[i-2], 17) ^ rightrotate( W[i- 2], 19) ^ (W[i-2] >> 10);
289 W[i] = W[i-16] + s0 + W[i-7] + s1;
302 for(
Uint32 j = 0; j < 64; ++j) {
303 Uint32 s0 = rightrotate( a, 2) ^ rightrotate( a, 13) ^ rightrotate( a, 22);
304 Uint32 maj = (a & b) ^ (a & c) ^ (b & c);
306 Uint32 s1 = rightrotate( e, 6) ^ rightrotate( e, 11) ^ rightrotate( e, 25);
307 Uint32 ch = (e & f) ^ ((~e) & g);
308 Uint32 t1 = h + s1 + ch + sha256_constants[j] + W[j];
310 h = g; g = f; f = e; e = d + t1;
311 d = c; c = b; b = a; a = t1 + t2;
315 state[0] += a; state[1] += b; state[2] += c; state[3] += d;
316 state[4] += e; state[5] += f; state[6] += g; state[7] += h;
320 for(
int i = 0; i < 8; ++i)
321 state[i] = flip32( state[i]);
323 memcpy( out_buffer, reinterpret_cast<char*>( state), 32);
334 #endif // MI_NEURAYLIB_ILIBRARY_AUTHENTICATION_H