mirror of
https://github.com/moonlight-stream/moonlight-common-c.git
synced 2025-08-18 01:15:46 +00:00
Switch to OpenSSL for input encryption with support for Gen 7 servers
This commit is contained in:
parent
48a5d63045
commit
d408372c34
@ -272,8 +272,7 @@ int LiStartConnection(const char* host, PSTREAM_CONFIGURATION streamConfig, PCON
|
||||
|
||||
Limelog("Initializing input stream...");
|
||||
ListenerCallbacks.stageStarting(STAGE_INPUT_STREAM_INIT);
|
||||
initializeInputStream(streamConfig->remoteInputAesKey, sizeof(streamConfig->remoteInputAesKey),
|
||||
streamConfig->remoteInputAesIv, sizeof(streamConfig->remoteInputAesIv));
|
||||
initializeInputStream();
|
||||
stage++;
|
||||
LC_ASSERT(stage == STAGE_INPUT_STREAM_INIT);
|
||||
ListenerCallbacks.stageComplete(STAGE_INPUT_STREAM_INIT);
|
||||
|
@ -4,19 +4,22 @@
|
||||
#include "LinkedBlockingQueue.h"
|
||||
#include "Input.h"
|
||||
|
||||
#include "OpenAES/oaes_lib.h"
|
||||
#include "OpenAES/oaes_common.h"
|
||||
#include <openssl/evp.h>
|
||||
|
||||
static SOCKET inputSock = INVALID_SOCKET;
|
||||
static unsigned char currentAesIv[16];
|
||||
static int initialized;
|
||||
static EVP_CIPHER_CTX cipherContext;
|
||||
static int cipherInitialized;
|
||||
|
||||
static LINKED_BLOCKING_QUEUE packetQueue;
|
||||
static PLT_THREAD inputSendThread;
|
||||
static OAES_CTX* oaesContext;
|
||||
|
||||
#define MAX_INPUT_PACKET_SIZE 128
|
||||
#define INPUT_STREAM_TIMEOUT_SEC 10
|
||||
|
||||
#define ROUND_TO_PKCS7_PADDED_LEN(x) ((((x) + 15) / 16) * 16)
|
||||
|
||||
// Contains input stream packets
|
||||
typedef struct _PACKET_HOLDER {
|
||||
int packetLength;
|
||||
@ -32,33 +35,12 @@ typedef struct _PACKET_HOLDER {
|
||||
} PACKET_HOLDER, *PPACKET_HOLDER;
|
||||
|
||||
// Initializes the input stream
|
||||
int initializeInputStream(char* aesKeyData, int aesKeyDataLength,
|
||||
char* aesIv, int aesIvLength) {
|
||||
if (aesIvLength != OAES_BLOCK_SIZE)
|
||||
{
|
||||
Limelog("AES IV is incorrect length. Should be %d\n", aesIvLength);
|
||||
return -1;
|
||||
}
|
||||
|
||||
oaesContext = oaes_alloc();
|
||||
if (oaesContext == NULL)
|
||||
{
|
||||
Limelog("Failed to allocate OpenAES context\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (oaes_set_option(oaesContext, OAES_OPTION_CBC, aesIv) != OAES_RET_SUCCESS)
|
||||
{
|
||||
Limelog("Failed to set CBC and IV on OAES context\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (oaes_key_import_data(oaesContext, (const unsigned char*)aesKeyData, aesKeyDataLength) != OAES_RET_SUCCESS)
|
||||
{
|
||||
Limelog("Failed to import AES key data\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int initializeInputStream(void) {
|
||||
memcpy(currentAesIv, StreamConfig.remoteInputAesIv, sizeof(currentAesIv));
|
||||
|
||||
// Initialized on first packet
|
||||
cipherInitialized = 0;
|
||||
|
||||
LbqInitializeLinkedBlockingQueue(&packetQueue, 30);
|
||||
|
||||
initialized = 1;
|
||||
@ -68,12 +50,10 @@ int initializeInputStream(char* aesKeyData, int aesKeyDataLength,
|
||||
// Destroys and cleans up the input stream
|
||||
void destroyInputStream(void) {
|
||||
PLINKED_BLOCKING_QUEUE_ENTRY entry, nextEntry;
|
||||
|
||||
if (oaesContext != NULL)
|
||||
{
|
||||
// FIXME: This crashes trying to free ctx->key
|
||||
// oaes_free(oaesContext);
|
||||
oaesContext = NULL;
|
||||
|
||||
if (cipherInitialized) {
|
||||
EVP_CIPHER_CTX_cleanup(&cipherContext);
|
||||
cipherInitialized = 0;
|
||||
}
|
||||
|
||||
entry = LbqDestroyLinkedBlockingQueue(&packetQueue);
|
||||
@ -119,14 +99,113 @@ static int checkDirs(short currentVal, short newVal, int* dir) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define OAES_DATA_OFFSET 32
|
||||
static int addPkcs7PaddingInPlace(unsigned char* plaintext, int plaintextLen) {
|
||||
int i;
|
||||
int paddedLength = ROUND_TO_PKCS7_PADDED_LEN(plaintextLen);
|
||||
unsigned char paddingByte = (unsigned char)(16 - (plaintextLen % 16));
|
||||
|
||||
for (i = plaintextLen; i < paddedLength; i++) {
|
||||
plaintext[i] = paddingByte;
|
||||
}
|
||||
|
||||
return paddedLength;
|
||||
}
|
||||
|
||||
static int encryptData(const unsigned char* plaintext, int plaintextLen,
|
||||
unsigned char* ciphertext, int* ciphertextLen) {
|
||||
int ret;
|
||||
int len;
|
||||
|
||||
if (ServerMajorVersion >= 7) {
|
||||
EVP_CIPHER_CTX_init(&cipherContext);
|
||||
|
||||
// Gen 7 servers use 128-bit AES GCM
|
||||
if (EVP_EncryptInit_ex(&cipherContext, EVP_aes_128_gcm(), NULL, NULL, NULL) != 1) {
|
||||
ret = -1;
|
||||
goto gcm_cleanup;
|
||||
}
|
||||
|
||||
// Gen 7 servers uses 16 byte IVs
|
||||
if (EVP_CIPHER_CTX_ctrl(&cipherContext, EVP_CTRL_GCM_SET_IVLEN, 16, NULL) != 1) {
|
||||
ret = -1;
|
||||
goto gcm_cleanup;
|
||||
}
|
||||
|
||||
// Initialize again but now provide our key and current IV
|
||||
if (EVP_EncryptInit_ex(&cipherContext, NULL, NULL,
|
||||
(const unsigned char*)StreamConfig.remoteInputAesKey, currentAesIv) != 1) {
|
||||
ret = -1;
|
||||
goto gcm_cleanup;
|
||||
}
|
||||
|
||||
// Encrypt into the caller's buffer, leaving room for the auth tag to be prepended
|
||||
if (EVP_EncryptUpdate(&cipherContext, &ciphertext[16], ciphertextLen, plaintext, plaintextLen) != 1) {
|
||||
ret = -1;
|
||||
goto gcm_cleanup;
|
||||
}
|
||||
|
||||
// GCM encryption won't ever fill ciphertext here but we have to call it anyway
|
||||
if (EVP_EncryptFinal_ex(&cipherContext, ciphertext, &len) != 1) {
|
||||
ret = -1;
|
||||
goto gcm_cleanup;
|
||||
}
|
||||
LC_ASSERT(len == 0);
|
||||
|
||||
// Read the tag into the caller's buffer
|
||||
if (EVP_CIPHER_CTX_ctrl(&cipherContext, EVP_CTRL_GCM_GET_TAG, 16, ciphertext) != 1) {
|
||||
ret = -1;
|
||||
goto gcm_cleanup;
|
||||
}
|
||||
|
||||
// Increment the ciphertextLen to account for the tag
|
||||
*ciphertextLen += 16;
|
||||
|
||||
ret = 0;
|
||||
|
||||
gcm_cleanup:
|
||||
EVP_CIPHER_CTX_cleanup(&cipherContext);
|
||||
}
|
||||
else {
|
||||
unsigned char paddedData[MAX_INPUT_PACKET_SIZE];
|
||||
int paddedLength;
|
||||
|
||||
if (!cipherInitialized) {
|
||||
EVP_CIPHER_CTX_init(&cipherContext);
|
||||
cipherInitialized = 1;
|
||||
|
||||
// Prior to Gen 7, 128-bit AES CBC is used for encryption
|
||||
if (EVP_EncryptInit_ex(&cipherContext, EVP_aes_128_cbc(), NULL,
|
||||
(const unsigned char*)StreamConfig.remoteInputAesKey, currentAesIv) != 1) {
|
||||
ret = -1;
|
||||
goto cbc_cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
// Pad the data to the required block length
|
||||
memcpy(paddedData, plaintext, plaintextLen);
|
||||
paddedLength = addPkcs7PaddingInPlace(paddedData, plaintextLen);
|
||||
|
||||
if (EVP_EncryptUpdate(&cipherContext, ciphertext, ciphertextLen, paddedData, paddedLength) != 1) {
|
||||
ret = -1;
|
||||
goto cbc_cleanup;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
cbc_cleanup:
|
||||
// Nothing to do
|
||||
;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Input thread proc
|
||||
static void inputSendThreadProc(void* context) {
|
||||
SOCK_RET err;
|
||||
PPACKET_HOLDER holder;
|
||||
char encryptedBuffer[MAX_INPUT_PACKET_SIZE];
|
||||
size_t encryptedSize;
|
||||
int encryptedSize;
|
||||
|
||||
while (!PltIsThreadInterrupted(&inputSendThread)) {
|
||||
int encryptedLengthPrefix;
|
||||
@ -238,29 +317,24 @@ static void inputSendThreadProc(void* context) {
|
||||
holder->packet.mouseMove.deltaY = htons((short)totalDeltaY);
|
||||
}
|
||||
|
||||
encryptedSize = sizeof(encryptedBuffer);
|
||||
err = oaes_encrypt(oaesContext, (const unsigned char*)&holder->packet, holder->packetLength,
|
||||
(unsigned char*)encryptedBuffer, &encryptedSize);
|
||||
// Encrypt the message into the output buffer while leaving room for the length
|
||||
encryptedSize = sizeof(encryptedBuffer) - 4;
|
||||
err = encryptData((const unsigned char*)&holder->packet, holder->packetLength,
|
||||
(unsigned char*)&encryptedBuffer[4], &encryptedSize);
|
||||
free(holder);
|
||||
if (err != OAES_RET_SUCCESS) {
|
||||
if (err != 0) {
|
||||
Limelog("Input: Encryption failed: %d\n", (int)err);
|
||||
ListenerCallbacks.connectionTerminated(err);
|
||||
return;
|
||||
}
|
||||
|
||||
// The first 32-bytes of the output are internal OAES stuff that we want to ignore
|
||||
encryptedSize -= OAES_DATA_OFFSET;
|
||||
|
||||
// Overwrite the last 4 bytes before the encrypted data with the length so
|
||||
// we can send the message all at once. GFE can choke if it gets the header
|
||||
// before the rest of the message.
|
||||
// Prepend the length to the message
|
||||
encryptedLengthPrefix = htonl((unsigned long)encryptedSize);
|
||||
memcpy(&encryptedBuffer[OAES_DATA_OFFSET - sizeof(encryptedLengthPrefix)],
|
||||
&encryptedLengthPrefix, sizeof(encryptedLengthPrefix));
|
||||
memcpy(&encryptedBuffer[0], &encryptedLengthPrefix, 4);
|
||||
|
||||
if (ServerMajorVersion < 5) {
|
||||
// Send the encrypted payload
|
||||
err = send(inputSock, (const char*) &encryptedBuffer[OAES_DATA_OFFSET - sizeof(encryptedLengthPrefix)],
|
||||
err = send(inputSock, (const char*) encryptedBuffer,
|
||||
(int) (encryptedSize + sizeof(encryptedLengthPrefix)), 0);
|
||||
if (err <= 0) {
|
||||
Limelog("Input: send() failed: %d\n", (int) LastSocketError());
|
||||
@ -269,7 +343,17 @@ static void inputSendThreadProc(void* context) {
|
||||
}
|
||||
}
|
||||
else {
|
||||
err = (SOCK_RET)sendInputPacketOnControlStream((unsigned char*) &encryptedBuffer[OAES_DATA_OFFSET - sizeof(encryptedLengthPrefix)],
|
||||
// For reasons that I can't understand, NVIDIA decides to use the last 16
|
||||
// bytes of ciphertext in the most recent game controller packet as the IV for
|
||||
// future encryption. I think it may be a buffer overrun on their end but we'll have
|
||||
// to mimic it to work correctly.
|
||||
if (ServerMajorVersion >= 7 && encryptedSize >= 16 + sizeof(currentAesIv)) {
|
||||
memcpy(currentAesIv,
|
||||
&encryptedBuffer[4 + encryptedSize - sizeof(currentAesIv)],
|
||||
sizeof(currentAesIv));
|
||||
}
|
||||
|
||||
err = (SOCK_RET)sendInputPacketOnControlStream((unsigned char*) encryptedBuffer,
|
||||
(int) (encryptedSize + sizeof(encryptedLengthPrefix)));
|
||||
if (err < 0) {
|
||||
Limelog("Input: sendInputPacketOnControlStream() failed: %d\n", (int) err);
|
||||
|
@ -56,7 +56,7 @@ void destroyAudioStream(void);
|
||||
int startAudioStream(void);
|
||||
void stopAudioStream(void);
|
||||
|
||||
int initializeInputStream(char* aesKeyData, int aesKeyDataLength, char* aesIv, int aesIvLength);
|
||||
int initializeInputStream(void);
|
||||
void destroyInputStream(void);
|
||||
int startInputStream(void);
|
||||
int stopInputStream(void);
|
||||
|
@ -1,27 +0,0 @@
|
||||
---------------------------------------------------------------------------
|
||||
OpenAES Licence
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 2012, Nabil S. Al Ramli, www.nalramli.com
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------
|
@ -1,85 +0,0 @@
|
||||
---------------------------------------------------------------------------
|
||||
OpenAES-0.9.0
|
||||
Nabil S. Al Ramli
|
||||
www.nalramli.com
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
License Terms
|
||||
-------------
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
OpenAES Licence
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 2012, Nabil S. Al Ramli, www.nalramli.com
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
OpenAES is an open source implementation of the Advanced Encryption
|
||||
Standard. It is distributed as a portable, lightweight C library that can
|
||||
be easily integrated into applications.
|
||||
|
||||
Compiling
|
||||
---------
|
||||
|
||||
OpenAES has been tested with the GCC as well as VC compilers. It is
|
||||
necessary to compile the source files located in ./src, and to add ./inc to
|
||||
the include paths.
|
||||
|
||||
If you are building with OAES_HAVE_ISAAC defined (true by default), then
|
||||
you also need to link in the source files under ./src/isaac and also add
|
||||
./src/isaac to the include paths.
|
||||
|
||||
You may edit ./inc/oaes_config.h to modify build options.
|
||||
|
||||
CMake 2.8.0 can be used to build the test programs on different platforms.
|
||||
|
||||
In a Linux command line terminal type:
|
||||
|
||||
cmake .
|
||||
make
|
||||
|
||||
In Windows, in a Visual Studio command line window type:
|
||||
|
||||
cmake . -G "NMake Makefiles"
|
||||
nmake
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
oaes_lib usage is described in the header file ./inc/oaes_lib.h.
|
||||
|
||||
The oaes command line application help manual can be obtained by using the
|
||||
--help command line options.
|
||||
|
||||
The oaes_setup Windows installer integrates with the Windows shell. It can be
|
||||
used by right clicking a file in Windows Explorer and then selecting a
|
||||
subcommand from the OpenAES menu.
|
||||
|
||||
Samples
|
||||
-------
|
||||
|
||||
Samples applications are provided in the /test folder.
|
@ -1 +0,0 @@
|
||||
OpenAES-0.9.0
|
@ -1,178 +0,0 @@
|
||||
/*
|
||||
* ---------------------------------------------------------------------------
|
||||
* OpenAES License
|
||||
* ---------------------------------------------------------------------------
|
||||
* Copyright (c) 2013, Nabil S. Al Ramli, www.nalramli.com
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
#if 0 // LIMELIGHT
|
||||
static const char _NR[] = {
|
||||
0x4e,0x61,0x62,0x69,0x6c,0x20,0x53,0x2e,0x20,
|
||||
0x41,0x6c,0x20,0x52,0x61,0x6d,0x6c,0x69,0x00 };
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "oaes_config.h"
|
||||
#include "oaes_base64.h"
|
||||
|
||||
static const char _oaes_base64_table[] =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
OAES_RET oaes_base64_encode(
|
||||
const uint8_t *in, size_t in_len, char *out, size_t *out_len)
|
||||
{
|
||||
size_t _i = 0, _j = 0;
|
||||
unsigned char _buf1[3];
|
||||
unsigned char _buf2[4];
|
||||
size_t _out_len_req = 4 * ( in_len / 3 + ( in_len % 3 ? 1 : 0 ) ) + 1;
|
||||
|
||||
if( NULL == in || 0 == in_len || NULL == out_len )
|
||||
return OAES_RET_ERROR;
|
||||
|
||||
if( NULL == out )
|
||||
{
|
||||
*out_len = _out_len_req;
|
||||
return OAES_RET_SUCCESS;
|
||||
}
|
||||
|
||||
if( _out_len_req > *out_len )
|
||||
return OAES_RET_ERROR;
|
||||
|
||||
memset(out, 0, *out_len);
|
||||
*out_len = 0;
|
||||
while( in_len-- )
|
||||
{
|
||||
_buf1[_i++] = *(in++);
|
||||
if( _i == 3 )
|
||||
{
|
||||
_buf2[0] = (_buf1[0] & 0xfc) >> 2;
|
||||
_buf2[1] = ((_buf1[0] & 0x03) << 4) + ((_buf1[1] & 0xf0) >> 4);
|
||||
_buf2[2] = ((_buf1[1] & 0x0f) << 2) + ((_buf1[2] & 0xc0) >> 6);
|
||||
_buf2[3] = _buf1[2] & 0x3f;
|
||||
|
||||
for( _i = 0; _i < 4; _i++ )
|
||||
{
|
||||
*(out++) = _oaes_base64_table[_buf2[_i]];
|
||||
(*out_len)++;
|
||||
}
|
||||
_i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if( _i )
|
||||
{
|
||||
for( _j = _i; _j < 3; _j++ )
|
||||
_buf1[_j] = '\0';
|
||||
|
||||
_buf2[0] = (_buf1[0] & 0xfc) >> 2;
|
||||
_buf2[1] = ((_buf1[0] & 0x03) << 4) + ((_buf1[1] & 0xf0) >> 4);
|
||||
_buf2[2] = ((_buf1[1] & 0x0f) << 2) + ((_buf1[2] & 0xc0) >> 6);
|
||||
_buf2[3] = _buf1[2] & 0x3f;
|
||||
|
||||
for( _j = 0; (_j < _i + 1); _j++ )
|
||||
{
|
||||
*(out++) = _oaes_base64_table[_buf2[_j]];
|
||||
(*out_len)++;
|
||||
}
|
||||
|
||||
while( _i++ < 3 )
|
||||
{
|
||||
*(out++) = '=';
|
||||
(*out_len)++;
|
||||
}
|
||||
}
|
||||
|
||||
return OAES_RET_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
OAES_RET oaes_base64_decode(
|
||||
const char *in, size_t in_len, uint8_t *out, size_t *out_len )
|
||||
{
|
||||
size_t _i = 0, _j = 0, _idx = 0;
|
||||
uint8_t _buf2[4], _buf1[3];
|
||||
size_t _out_len_req = 3 * ( in_len / 4 + ( in_len % 4 ? 1 : 0 ) );
|
||||
|
||||
if( NULL == in || 0 == in_len || NULL == out_len )
|
||||
return OAES_RET_ERROR;
|
||||
|
||||
if( NULL == out )
|
||||
{
|
||||
*out_len = _out_len_req;
|
||||
return OAES_RET_SUCCESS;
|
||||
}
|
||||
|
||||
if( _out_len_req > *out_len )
|
||||
return OAES_RET_ERROR;
|
||||
|
||||
// Satisfy overzealous compiler
|
||||
memset(_buf1, 0, sizeof(_buf1));
|
||||
|
||||
memset(out, 0, *out_len);
|
||||
*out_len = 0;
|
||||
while( in_len-- && strchr(_oaes_base64_table, in[_idx++]) )
|
||||
{
|
||||
_buf2[_i++] = in[_idx - 1];
|
||||
if( _i ==4 )
|
||||
{
|
||||
for (_i = 0; _i < 4; _i++)
|
||||
_buf2[_i] = strchr(_oaes_base64_table, _buf2[_i]) - _oaes_base64_table;
|
||||
|
||||
_buf1[0] = (_buf2[0] << 2) + ((_buf2[1] & 0x30) >> 4);
|
||||
_buf1[1] = ((_buf2[1] & 0xf) << 4) + ((_buf2[2] & 0x3c) >> 2);
|
||||
_buf1[2] = ((_buf2[2] & 0x3) << 6) + _buf2[3];
|
||||
|
||||
for( _i = 0; (_i < 3); _i++ )
|
||||
{
|
||||
*(out++) = _buf1[_i];
|
||||
(*out_len)++;
|
||||
}
|
||||
_i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if( _i )
|
||||
{
|
||||
for( _j = _i; _j <4; _j++ )
|
||||
_buf2[_j] = 0;
|
||||
|
||||
for( _j = 0; _j <4; _j++ )
|
||||
_buf2[_j] = strchr(_oaes_base64_table, _buf2[_j]) - _oaes_base64_table;
|
||||
|
||||
_buf1[0] = (_buf2[0] << 2) + ((_buf2[1] & 0x30) >> 4);
|
||||
_buf1[1] = ((_buf2[1] & 0xf) << 4) + ((_buf2[2] & 0x3c) >> 2);
|
||||
_buf1[2] = ((_buf2[2] & 0x3) << 6) + _buf2[3];
|
||||
|
||||
for( _j = 0; (_j < _i - 1); _j++ )
|
||||
{
|
||||
*(out++) = _buf1[_j];
|
||||
(*out_len)++;
|
||||
}
|
||||
}
|
||||
|
||||
return OAES_RET_SUCCESS;
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
/*
|
||||
* ---------------------------------------------------------------------------
|
||||
* OpenAES License
|
||||
* ---------------------------------------------------------------------------
|
||||
* Copyright (c) 2013, Nabil S. Al Ramli, www.nalramli.com
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef _OAES_BASE64_H
|
||||
#define _OAES_BASE64_H
|
||||
|
||||
#include "oaes_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
OAES_API OAES_RET oaes_base64_encode(
|
||||
const uint8_t *in, size_t in_len, char *out, size_t *out_len );
|
||||
|
||||
OAES_API OAES_RET oaes_base64_decode(
|
||||
const char *in, size_t in_len, uint8_t *out, size_t *out_len );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _OAES_BASE64_H
|
@ -1,77 +0,0 @@
|
||||
/*
|
||||
* ---------------------------------------------------------------------------
|
||||
* OpenAES License
|
||||
* ---------------------------------------------------------------------------
|
||||
* Copyright (c) 2013, Nabil S. Al Ramli, www.nalramli.com
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef _OAES_COMMON_H
|
||||
#define _OAES_COMMON_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifdef OAES_SHARED
|
||||
# ifdef oaes_lib_EXPORTS
|
||||
# define OAES_API __declspec(dllexport)
|
||||
# else
|
||||
# define OAES_API __declspec(dllimport)
|
||||
# endif
|
||||
# else
|
||||
# define OAES_API
|
||||
# endif
|
||||
#else
|
||||
# define OAES_API
|
||||
#endif // WIN32
|
||||
|
||||
#define OAES_VERSION "0.9.0"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
OAES_RET_FIRST = 0,
|
||||
OAES_RET_SUCCESS = 0,
|
||||
OAES_RET_ERROR,
|
||||
OAES_RET_ARG1,
|
||||
OAES_RET_ARG2,
|
||||
OAES_RET_ARG3,
|
||||
OAES_RET_ARG4,
|
||||
OAES_RET_ARG5,
|
||||
OAES_RET_NOKEY,
|
||||
OAES_RET_MEM,
|
||||
OAES_RET_BUF,
|
||||
OAES_RET_HEADER,
|
||||
OAES_RET_COUNT
|
||||
} OAES_RET;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _OAES_COMMON_H
|
@ -1,42 +0,0 @@
|
||||
/*
|
||||
* ---------------------------------------------------------------------------
|
||||
* OpenAES License
|
||||
* ---------------------------------------------------------------------------
|
||||
* Copyright (c) 2012, Nabil S. Al Ramli, www.nalramli.com
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef _OAES_CONFIG_H
|
||||
#define _OAES_CONFIG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _OAES_CONFIG_H
|
File diff suppressed because it is too large
Load Diff
@ -1,168 +0,0 @@
|
||||
/*
|
||||
* ---------------------------------------------------------------------------
|
||||
* OpenAES License
|
||||
* ---------------------------------------------------------------------------
|
||||
* Copyright (c) 2013, Nabil S. Al Ramli, www.nalramli.com
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef _OAES_LIB_H
|
||||
#define _OAES_LIB_H
|
||||
|
||||
#include "oaes_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifdef OAES_SHARED
|
||||
# ifdef oaes_lib_EXPORTS
|
||||
# define OAES_API __declspec(dllexport)
|
||||
# else
|
||||
# define OAES_API __declspec(dllimport)
|
||||
# endif
|
||||
# else
|
||||
# define OAES_API
|
||||
# endif
|
||||
#else
|
||||
# define OAES_API
|
||||
#endif // WIN32
|
||||
|
||||
#define OAES_BLOCK_SIZE 16
|
||||
|
||||
typedef void OAES_CTX;
|
||||
|
||||
/*
|
||||
* oaes_set_option() takes one of these values for its [option] parameter
|
||||
* some options accept either an optional or a required [value] parameter
|
||||
*/
|
||||
// no option
|
||||
#define OAES_OPTION_NONE 0
|
||||
// enable ECB mode, disable CBC mode
|
||||
#define OAES_OPTION_ECB 1
|
||||
// enable CBC mode, disable ECB mode
|
||||
// value is optional, may pass uint8_t iv[OAES_BLOCK_SIZE] to specify
|
||||
// the value of the initialization vector, iv
|
||||
#define OAES_OPTION_CBC 2
|
||||
|
||||
#ifdef OAES_DEBUG
|
||||
typedef int ( * oaes_step_cb ) (
|
||||
const uint8_t state[OAES_BLOCK_SIZE],
|
||||
const char * step_name,
|
||||
int step_count,
|
||||
void * user_data );
|
||||
// enable state stepping mode
|
||||
// value is required, must pass oaes_step_cb to receive the state at each step
|
||||
#define OAES_OPTION_STEP_ON 4
|
||||
// disable state stepping mode
|
||||
#define OAES_OPTION_STEP_OFF 8
|
||||
#endif // OAES_DEBUG
|
||||
|
||||
typedef uint16_t OAES_OPTION;
|
||||
|
||||
/*
|
||||
* // usage:
|
||||
*
|
||||
* OAES_CTX * ctx = oaes_alloc();
|
||||
* .
|
||||
* .
|
||||
* .
|
||||
* {
|
||||
* oaes_gen_key_xxx( ctx );
|
||||
* {
|
||||
* oaes_key_export( ctx, _buf, &_buf_len );
|
||||
* // or
|
||||
* oaes_key_export_data( ctx, _buf, &_buf_len );\
|
||||
* }
|
||||
* }
|
||||
* // or
|
||||
* {
|
||||
* oaes_key_import( ctx, _buf, _buf_len );
|
||||
* // or
|
||||
* oaes_key_import_data( ctx, _buf, _buf_len );
|
||||
* }
|
||||
* .
|
||||
* .
|
||||
* .
|
||||
* oaes_encrypt( ctx, m, m_len, c, &c_len );
|
||||
* .
|
||||
* .
|
||||
* .
|
||||
* oaes_decrypt( ctx, c, c_len, m, &m_len );
|
||||
* .
|
||||
* .
|
||||
* .
|
||||
* oaes_free( &ctx );
|
||||
*/
|
||||
|
||||
OAES_API OAES_CTX * oaes_alloc();
|
||||
|
||||
OAES_API OAES_RET oaes_free( OAES_CTX ** ctx );
|
||||
|
||||
OAES_API OAES_RET oaes_set_option( OAES_CTX * ctx,
|
||||
OAES_OPTION option, const void * value );
|
||||
|
||||
OAES_API OAES_RET oaes_key_gen_128( OAES_CTX * ctx );
|
||||
|
||||
OAES_API OAES_RET oaes_key_gen_192( OAES_CTX * ctx );
|
||||
|
||||
OAES_API OAES_RET oaes_key_gen_256( OAES_CTX * ctx );
|
||||
|
||||
// export key with header information
|
||||
// set data == NULL to get the required data_len
|
||||
OAES_API OAES_RET oaes_key_export( OAES_CTX * ctx,
|
||||
uint8_t * data, size_t * data_len );
|
||||
|
||||
// directly export the data from key
|
||||
// set data == NULL to get the required data_len
|
||||
OAES_API OAES_RET oaes_key_export_data( OAES_CTX * ctx,
|
||||
uint8_t * data, size_t * data_len );
|
||||
|
||||
// import key with header information
|
||||
OAES_API OAES_RET oaes_key_import( OAES_CTX * ctx,
|
||||
const uint8_t * data, size_t data_len );
|
||||
|
||||
// directly import data into key
|
||||
OAES_API OAES_RET oaes_key_import_data( OAES_CTX * ctx,
|
||||
const uint8_t * data, size_t data_len );
|
||||
|
||||
// set c == NULL to get the required c_len
|
||||
OAES_API OAES_RET oaes_encrypt( OAES_CTX * ctx,
|
||||
const uint8_t * m, size_t m_len, uint8_t * c, size_t * c_len );
|
||||
|
||||
// set m == NULL to get the required m_len
|
||||
OAES_API OAES_RET oaes_decrypt( OAES_CTX * ctx,
|
||||
const uint8_t * c, size_t c_len, uint8_t * m, size_t * m_len );
|
||||
|
||||
// set buf == NULL to get the required buf_len
|
||||
OAES_API OAES_RET oaes_sprintf(
|
||||
char * buf, size_t * buf_len, const uint8_t * data, size_t data_len );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _OAES_LIB_H
|
Loading…
x
Reference in New Issue
Block a user