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>
35 class ILibrary_authenticator :
public
43 mi::base::Interface_declare<0x5a7d010a,0x2a65,0x43da,0x92,0xf2,0xcd,0xd9,0xc8,0x4b,0x10,0xd2>
68 const INeuray* library,
69 const char* vendor_key,
Size vendor_key_length,
70 const char* secret_key,
Size secret_key_length,
88 virtual Size get_challenge(
char* buffer,
Size buffer_length) = 0;
105 virtual void submit_challenge_response(
106 const char* response,
Size response_length,
107 const char* vendor_key,
Size vendor_key_length,
108 const char* salt,
Size salt_length,
182 static void generate_nounce(
char* buffer);
191 static void calculate_response(
192 const char* salt,
const char* challenge,
193 const char* secret_key,
Size secret_key_length,
char* response);
200 static void sha256(
const char* input,
unsigned int input_length,
char* buffer);
206 const char* vendor_key,
Size vendor_key_length,
207 const char* secret_key,
Size secret_key_length,
219 memset( &challenge[0], 0, 32);
220 if( authenticator->get_challenge( challenge,
sizeof( challenge)) >
sizeof( challenge))
224 detail::generate_nounce( salt);
227 detail::calculate_response( salt, challenge, secret_key, secret_key_length, response);
229 authenticator->submit_challenge_response(
230 response,
sizeof( response), vendor_key, vendor_key_length, salt,
sizeof( salt), count);
236 void calculate_response(
237 const char* salt,
const char* challenge,
238 const char* secret_key,
Size secret_key_length,
char* response)
240 if( secret_key_length > 1024u * 10u)
243 Size total_len = 32u + 32u + secret_key_length;
244 char* buffer =
new char[total_len];
245 memcpy( buffer, salt, 32);
246 memcpy( buffer + 32, challenge, 32);
247 memcpy( buffer + 64, secret_key, secret_key_length);
248 sha256( buffer, static_cast<Uint32>( total_len), response);
252 void generate_nounce(
char* buffer)
257 #ifdef MI_PLATFORM_WINDOWS
258 srand( GetTickCount());
260 QueryPerformanceCounter( &tmp);
261 number += tmp.QuadPart + GetCurrentProcessId() + GetTickCount();
265 srand( static_cast<unsigned>( time( 0)));
267 gettimeofday( &tv, 0);
268 number +=
static_cast<Uint64>( tv.tv_sec + tv.tv_usec);
272 memcpy( buf, &r,
sizeof(
Uint32));
273 memcpy( buf +
sizeof(
Uint32), &number,
sizeof(
Uint64));
275 number +=
static_cast<Uint64>( rand());
277 sha256( buf, static_cast<Uint32>(
sizeof( buf)), buffer);
282 static const Uint32 sha256_constants[] = {
283 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
284 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
285 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
286 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
287 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
288 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
289 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
290 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
296 return ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) |
297 (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24));
303 return (( x >> y) | (x << (32-y)));
306 void sha256(
const char* input,
unsigned int input_length,
char* buffer)
308 if( (input_length <= 0) || (input == 0) || (buffer == 0))
312 Uint32 state[] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
313 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
316 unsigned int r = (input_length * 8 + 1) % 512;
317 unsigned int k = r > 448 ? 960 - r : 448 - r;
319 unsigned int pos = 0;
320 for(
unsigned int chunk = 0; k != 0; ++chunk) {
324 unsigned int to_copy = input_length - pos;
325 to_copy = to_copy > 64 ? 64 : to_copy;
327 memcpy( ptr, input + pos, to_copy);
332 if( pos == input_length) {
334 if( (k > 0) && (pos % 64 < 64) && (pos/64 == chunk))
335 ptr[pos%64] |=
static_cast<Uint8>( 0x80);
337 if( (pos*8 + 1 + k) - (chunk*512) <= 448) {
338 Uint64 value = input_length * 8;
339 ptr =
reinterpret_cast<Uint8*
>(&W[14]);
343 ptr[0] =
static_cast<Uint8>((value >> 56) & 0xff);
344 ptr[1] =
static_cast<Uint8>((value >> 48) & 0xff);
345 ptr[2] =
static_cast<Uint8>((value >> 40) & 0xff);
346 ptr[3] =
static_cast<Uint8>((value >> 32) & 0xff);
347 ptr[4] =
static_cast<Uint8>((value >> 24) & 0xff);
348 ptr[5] =
static_cast<Uint8>((value >> 16) & 0xff);
349 ptr[6] =
static_cast<Uint8>((value >> 8) & 0xff);
350 ptr[7] =
static_cast<Uint8>( value & 0xff);
356 for(
int i = 0; i < 16; ++i)
357 W[i] = flip32( W[i]);
360 for(
Uint32 i = 16; i < 64; ++i) {
361 Uint32 s0 = rightrotate( W[i-15], 7) ^ rightrotate( W[i-15], 18) ^ (W[i-15] >> 3);
362 Uint32 s1 = rightrotate( W[i-2], 17) ^ rightrotate( W[i- 2], 19) ^ (W[i-2] >> 10);
363 W[i] = W[i-16] + s0 + W[i-7] + s1;
376 for(
Uint32 j = 0; j < 64; ++j) {
377 Uint32 s0 = rightrotate( a, 2) ^ rightrotate( a, 13) ^ rightrotate( a, 22);
378 Uint32 maj = (a & b) ^ (a & c) ^ (b & c);
380 Uint32 s1 = rightrotate( e, 6) ^ rightrotate( e, 11) ^ rightrotate( e, 25);
381 Uint32 ch = (e & f) ^ ((~e) & g);
382 Uint32 t1 = h + s1 + ch + sha256_constants[j] + W[j];
384 h = g; g = f; f = e; e = d + t1;
385 d = c; c = b; b = a; a = t1 + t2;
389 state[0] += a; state[1] += b; state[2] += c; state[3] += d;
390 state[4] += e; state[5] += f; state[6] += g; state[7] += h;
394 for(
int i = 0; i < 8; ++i)
395 state[i] = flip32( state[i]);
397 memcpy( buffer, reinterpret_cast<char*>( state), 32);
406 #endif // MI_NEURAYLIB_ILIBRARY_AUTHENTICATION_H