forked from 0ad/0ad
Seperate differently licenced portions of sha.cpp/h into pkcs5_pdkdf2.cpp/h and remove some extra std includes in sha.cpp. Refs #2308
This was SVN commit r14350.
This commit is contained in:
parent
bf97148ddc
commit
f890856c6d
98
source/lobby/pkcs5_pbkdf2.cpp
Normal file
98
source/lobby/pkcs5_pbkdf2.cpp
Normal file
@ -0,0 +1,98 @@
|
||||
/**
|
||||
* Copyright (c) 2008 Damien Bergamini <damien.bergamini@free.fr>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
// This file is based loosly off libutil/pkcs5_pbkdf2.c in OpenBSD.
|
||||
|
||||
#include "pkcs5_pbkdf2.h"
|
||||
#include "sha.h"
|
||||
|
||||
static void hmac_sha256(unsigned char (&digest)[SHA_DIGEST_SIZE],
|
||||
const unsigned char* text, size_t text_len,
|
||||
const unsigned char* key, size_t key_len)
|
||||
{
|
||||
SHA256 hash;
|
||||
unsigned char tk[SHA_DIGEST_SIZE]; // temporary key incase we need to pad the key with zero unsigned chars
|
||||
if (key_len > SHA_DIGEST_SIZE)
|
||||
{
|
||||
hash.update(key, key_len);
|
||||
hash.finish(tk);
|
||||
key = tk;
|
||||
key_len = SHA_DIGEST_SIZE;
|
||||
}
|
||||
|
||||
unsigned char k_pad[SHA_DIGEST_SIZE];
|
||||
|
||||
memset(k_pad, 0, sizeof k_pad);
|
||||
memcpy(k_pad, key, key_len);
|
||||
for (int i = 0; i < SHA_DIGEST_SIZE; ++i)
|
||||
k_pad[i] ^= 0x36;
|
||||
hash.init();
|
||||
hash.update(k_pad, SHA_DIGEST_SIZE);
|
||||
hash.update(text, text_len);
|
||||
hash.finish(digest);
|
||||
|
||||
|
||||
memset(k_pad, 0, sizeof k_pad);
|
||||
memcpy(k_pad, key, key_len);
|
||||
for (int i = 0; i < SHA_DIGEST_SIZE; ++i)
|
||||
k_pad[i] ^= 0x5c;
|
||||
|
||||
hash.init();
|
||||
hash.update(k_pad, SHA_DIGEST_SIZE);
|
||||
hash.update(digest, SHA_DIGEST_SIZE);
|
||||
hash.finish(digest);
|
||||
}
|
||||
|
||||
|
||||
int pbkdf2(unsigned char (&output)[SHA_DIGEST_SIZE],
|
||||
const unsigned char* key, size_t key_len,
|
||||
const unsigned char* salt, size_t salt_len,
|
||||
unsigned rounds)
|
||||
{
|
||||
unsigned char asalt[SHA_DIGEST_SIZE + 4], obuf[SHA_DIGEST_SIZE], d1[SHA_DIGEST_SIZE], d2[SHA_DIGEST_SIZE];
|
||||
|
||||
if (rounds < 1 || key_len == 0 || salt_len == 0)
|
||||
return -1;
|
||||
|
||||
if (salt_len > SHA_DIGEST_SIZE) salt_len = SHA_DIGEST_SIZE; // length cap for the salt
|
||||
memset(asalt, 0, salt_len);
|
||||
memcpy(asalt, salt, salt_len);
|
||||
|
||||
for (unsigned count = 1; ; ++count)
|
||||
{
|
||||
asalt[salt_len + 0] = (count >> 24) & 0xff;
|
||||
asalt[salt_len + 1] = (count >> 16) & 0xff;
|
||||
asalt[salt_len + 2] = (count >> 8) & 0xff;
|
||||
asalt[salt_len + 3] = count & 0xff;
|
||||
hmac_sha256(d1, asalt, salt_len + 4, key, key_len);
|
||||
memcpy(obuf, d1, SHA_DIGEST_SIZE);
|
||||
|
||||
for (unsigned i = 1; i < rounds; i++)
|
||||
{
|
||||
hmac_sha256(d2, d1, SHA_DIGEST_SIZE, key, key_len);
|
||||
memcpy(d1, d2, SHA_DIGEST_SIZE);
|
||||
for (unsigned j = 0; j < SHA_DIGEST_SIZE; j++)
|
||||
obuf[j] ^= d1[j];
|
||||
}
|
||||
|
||||
memcpy(output, obuf, SHA_DIGEST_SIZE);
|
||||
key += SHA_DIGEST_SIZE;
|
||||
if (key_len < SHA_DIGEST_SIZE)
|
||||
break;
|
||||
key_len -= SHA_DIGEST_SIZE;
|
||||
};
|
||||
return 0;
|
||||
}
|
||||
|
44
source/lobby/pkcs5_pbkdf2.h
Normal file
44
source/lobby/pkcs5_pbkdf2.h
Normal file
@ -0,0 +1,44 @@
|
||||
/* Copyright (c) 2013 Wildfire Games
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef PKCS5_PBKD2_INCLUDED
|
||||
#define PKCS5_PBKD2_INCLUDED
|
||||
|
||||
#define SHA_DIGEST_SIZE 32
|
||||
|
||||
|
||||
/**
|
||||
* Simple PBKDF2 implementation for hard to crack passwords
|
||||
* @param output The output buffer for the digested hash
|
||||
* @param key The initial key we want to hash
|
||||
* @param key_len Length of the key in bytes
|
||||
* @param salt The salt we use to iteratively hash the key.
|
||||
* @param salt_len Length of the salt in bytes
|
||||
* @param iterations Number of salting iterations
|
||||
* @return 0 on success, -1 on error
|
||||
*/
|
||||
int pbkdf2(unsigned char (&output)[SHA_DIGEST_SIZE],
|
||||
const unsigned char* key, size_t key_len,
|
||||
const unsigned char* salt, size_t salt_len,
|
||||
unsigned iterations);
|
||||
|
||||
#endif // PKCS5_PBKD2_INCLUDED
|
@ -22,6 +22,7 @@
|
||||
#include "gui/GUIManager.h"
|
||||
#include "lib/utf8.h"
|
||||
#include "lobby/IXmppClient.h"
|
||||
#include "lobby/pkcs5_pbkdf2.h"
|
||||
#include "lobby/sha.h"
|
||||
|
||||
#include "scriptinterface/ScriptInterface.h"
|
||||
|
@ -22,9 +22,6 @@
|
||||
|
||||
#include "sha.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define GET_uint32(n,b,i) \
|
||||
{ \
|
||||
(n) = ( (unsigned int) (b)[(i) ] << 24 ) \
|
||||
@ -266,98 +263,4 @@ void SHA256::finish(unsigned char (&digest)[32] )
|
||||
PUT_uint32( state[6], digest, 24 );
|
||||
PUT_uint32( state[7], digest, 28 );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copyright (c) 2008 Damien Bergamini <damien.bergamini@free.fr>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
// Next two functions are based very loosely off the functions in libutil/pkcs5_pbkdf2.c in OpenBSD.
|
||||
static void hmac_sha256(unsigned char (&digest)[SHA_DIGEST_SIZE],
|
||||
const unsigned char* text, size_t text_len,
|
||||
const unsigned char* key, size_t key_len)
|
||||
{
|
||||
SHA256 hash;
|
||||
unsigned char tk[SHA_DIGEST_SIZE]; // temporary key incase we need to pad the key with zero unsigned chars
|
||||
if (key_len > SHA_DIGEST_SIZE)
|
||||
{
|
||||
hash.update(key, key_len);
|
||||
hash.finish(tk);
|
||||
key = tk;
|
||||
key_len = SHA_DIGEST_SIZE;
|
||||
}
|
||||
|
||||
unsigned char k_pad[SHA_DIGEST_SIZE];
|
||||
|
||||
memset(k_pad, 0, sizeof k_pad);
|
||||
memcpy(k_pad, key, key_len);
|
||||
for (int i = 0; i < SHA_DIGEST_SIZE; ++i)
|
||||
k_pad[i] ^= 0x36;
|
||||
hash.init();
|
||||
hash.update(k_pad, SHA_DIGEST_SIZE);
|
||||
hash.update(text, text_len);
|
||||
hash.finish(digest);
|
||||
|
||||
|
||||
memset(k_pad, 0, sizeof k_pad);
|
||||
memcpy(k_pad, key, key_len);
|
||||
for (int i = 0; i < SHA_DIGEST_SIZE; ++i)
|
||||
k_pad[i] ^= 0x5c;
|
||||
|
||||
hash.init();
|
||||
hash.update(k_pad, SHA_DIGEST_SIZE);
|
||||
hash.update(digest, SHA_DIGEST_SIZE);
|
||||
hash.finish(digest);
|
||||
}
|
||||
|
||||
|
||||
int pbkdf2(unsigned char (&output)[SHA_DIGEST_SIZE],
|
||||
const unsigned char* key, size_t key_len,
|
||||
const unsigned char* salt, size_t salt_len,
|
||||
unsigned rounds)
|
||||
{
|
||||
unsigned char asalt[SHA_DIGEST_SIZE + 4], obuf[SHA_DIGEST_SIZE], d1[SHA_DIGEST_SIZE], d2[SHA_DIGEST_SIZE];
|
||||
|
||||
if (rounds < 1 || key_len == 0 || salt_len == 0)
|
||||
return -1;
|
||||
|
||||
if (salt_len > SHA_DIGEST_SIZE) salt_len = SHA_DIGEST_SIZE; // length cap for the salt
|
||||
memset(asalt, 0, salt_len);
|
||||
memcpy(asalt, salt, salt_len);
|
||||
|
||||
for (unsigned count = 1; ; ++count)
|
||||
{
|
||||
asalt[salt_len + 0] = (count >> 24) & 0xff;
|
||||
asalt[salt_len + 1] = (count >> 16) & 0xff;
|
||||
asalt[salt_len + 2] = (count >> 8) & 0xff;
|
||||
asalt[salt_len + 3] = count & 0xff;
|
||||
hmac_sha256(d1, asalt, salt_len + 4, key, key_len);
|
||||
memcpy(obuf, d1, SHA_DIGEST_SIZE);
|
||||
|
||||
for (unsigned i = 1; i < rounds; i++)
|
||||
{
|
||||
hmac_sha256(d2, d1, SHA_DIGEST_SIZE, key, key_len);
|
||||
memcpy(d1, d2, SHA_DIGEST_SIZE);
|
||||
for (unsigned j = 0; j < SHA_DIGEST_SIZE; j++)
|
||||
obuf[j] ^= d1[j];
|
||||
}
|
||||
|
||||
memcpy(output, obuf, SHA_DIGEST_SIZE);
|
||||
key += SHA_DIGEST_SIZE;
|
||||
if (key_len < SHA_DIGEST_SIZE)
|
||||
break;
|
||||
key_len -= SHA_DIGEST_SIZE;
|
||||
};
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -23,8 +23,6 @@
|
||||
#ifndef SHA_INCLUDED
|
||||
#define SHA_INCLUDED
|
||||
|
||||
#define SHA_DIGEST_SIZE 32
|
||||
|
||||
/**
|
||||
* Structure for performing SHA256 encryption on arbitrary data
|
||||
*/
|
||||
@ -41,20 +39,4 @@ struct SHA256
|
||||
void finish(unsigned char (&digest)[32]);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Simple PBKDF2 implementation for hard to crack passwords
|
||||
* @param output The output buffer for the digested hash
|
||||
* @param key The initial key we want to hash
|
||||
* @param key_len Length of the key in bytes
|
||||
* @param salt The salt we use to iteratively hash the key.
|
||||
* @param salt_len Length of the salt in bytes
|
||||
* @param iterations Number of salting iterations
|
||||
* @return 0 on success, -1 on error
|
||||
*/
|
||||
int pbkdf2(unsigned char (&output)[SHA_DIGEST_SIZE],
|
||||
const unsigned char* key, size_t key_len,
|
||||
const unsigned char* salt, size_t salt_len,
|
||||
unsigned iterations);
|
||||
|
||||
#endif // SHA_INCLUDED
|
||||
|
Loading…
Reference in New Issue
Block a user