You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
dvmhost/src/common/RC4Crypto.cpp

101 lines
2.5 KiB

// SPDX-License-Identifier: MIT
/*
* Digital Voice Modem - Common Library
* MIT Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright (C) 2024 Bryan Biedenkapp, N2PLL
*
*/
#include "Defines.h"
#include "RC4Crypto.h"
#include "Log.h"
#include "Utils.h"
using namespace crypto;
#include <cassert>
#include <cstring>
#include <string>
// ---------------------------------------------------------------------------
// Public Class Members
// ---------------------------------------------------------------------------
/* Initializes a new instance of the AES class. */
RC4::RC4() = default;
/* Encrypt/Decrypt input buffer with given key. */
uint8_t* RC4::crypt(const uint8_t in[], uint32_t inLen, const uint8_t key[], uint32_t keyLen)
{
uint8_t permutation[RC4_PERMUTATION_CNT];
::memset(permutation, 0x00U, RC4_PERMUTATION_CNT);
init(key, keyLen, permutation);
uint8_t* out = new uint8_t[inLen];
::memset(out, 0x00U, inLen);
transform(in, inLen, permutation, out);
return out;
}
// ---------------------------------------------------------------------------
// Private Class Members
// ---------------------------------------------------------------------------
/* */
void RC4::swap(uint8_t* a, uint8_t i1, uint8_t i2)
{
uint8_t temp = a[i1];
a[i1] = a[i2];
a[i2] = temp;
}
/* */
void RC4::init(const uint8_t key[], uint8_t keyLen, uint8_t* permutation)
{
assert(permutation != nullptr);
// init state variable
for (uint32_t i = 0U; i < RC4_PERMUTATION_CNT; i++)
permutation[i] = (uint8_t)i;
m_i1 = 0U;
m_i2 = 0U;
// randomize, using key
for (int j = 0, i = 0; i < 256; i++) {
j = (j + permutation[i] + key[i % keyLen]) % RC4_PERMUTATION_CNT;
// swap permutation[i] and permutation[j]
swap(permutation, i, j);
}
}
/* */
void RC4::transform(const uint8_t* input, uint32_t length, uint8_t* permutation, uint8_t* output)
{
assert(input != nullptr);
assert(output != nullptr);
uint32_t i = 0U, j = 0U;
for (; i < length; i++, j++) {
// update indices
m_i1 = (uint8_t)((m_i1 + 1) % RC4_PERMUTATION_CNT);
m_i2 = (uint8_t)((m_i2 + permutation[m_i1]) % RC4_PERMUTATION_CNT);
// swap permutation[m_i1] and permutation[m_i2]
swap(permutation, m_i1, m_i2);
// transform byte
uint8_t b = (uint8_t)((permutation[m_i1] + permutation[m_i2]) % RC4_PERMUTATION_CNT);
output[j] = (uint8_t)(input[i] ^ permutation[b]);
}
}

Powered by TurnKey Linux.