Skip to content

Commit

Permalink
Implement MISRA compliant Vernam cipher/One Time Pad algorithm
Browse files Browse the repository at this point in the history
- Vernam cipher/One Time Pad algorithm - MISRA compliant
  • Loading branch information
jciberlin committed Jun 9, 2024
1 parent f6ce64e commit 395590f
Show file tree
Hide file tree
Showing 6 changed files with 208 additions and 1 deletion.
62 changes: 62 additions & 0 deletions Inc/crypto/vernam_cipher.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/****************************************************************************
*
* Copyright (c) 2024 IMProject Development Team. All rights reserved.
* Authors: Juraj Ciberlin <[email protected]>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name IMProject nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* 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 OWNER 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 VERNAM_CIPHER_H_
#define VERNAM_CIPHER_H_

#include "typedefs.h"

/**
* @brief Encryption using Vernam cipher/One Time Pad algorithm.
*
* @param[in/out] *msg Pointer to message that will be encrypted.
* @param[in] *key Pointer to key string.
* @param[in] key_length Key length.
*
* @return Status of encryption function. True if message size is higher than or equal to key length, otherwise false.
*/
bool VernamCipher_encrypt(char* msg, const char* key, int32_t key_length);

/**
* @brief Decryption using Vernam cipher/One Time Pad algorithm.
*
* @param[in/out] *msg Pointer to message that will be decrypted.
* @param[in] *key Pointer to key string.
* @param[in] key_length Key length.
*
* @return Status of decryption function. True if message size is higher than or equal to key length, otherwise false.
*/
bool VernamCipher_decrypt(char* msg, const char* key, int32_t key_length);

#endif /* VERNAM_CIPHER_H_ */
4 changes: 3 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ IMUTILITY_FILES=\
Src/crc/crc32_variants/crc32_xfer.c \
Src/crypto/caesar_cipher.c \
Src/crypto/chacha20.c \
Src/crypto/vernam_cipher.c \
Src/sort/bubble_sort.c \
Src/sort/heap_sort.c \
Src/sort/insertion_sort.c \
Expand Down Expand Up @@ -139,7 +140,8 @@ SRC_FILES+=$(IMUTILITY_FILES) \
Tests/test_queue.c \
Tests/test_scheduler.c \
Tests/test_selection_sort.c \
Tests/test_utils.c
Tests/test_utils.c \
Tests/test_vernam_cipher.c

INC_DIRS_CODE= \
-IInc \
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ Join us on the Discord channel https://discord.gg/R6nZxZqDH3
- CaesarCipher_encrypt
- CaesarCipher_decrypt
- Chacha20_crypt
- VernamCipher_encrypt
- VernamCipher_decrypt

### JSON
- Json_startString
Expand Down
105 changes: 105 additions & 0 deletions Src/crypto/vernam_cipher.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/****************************************************************************
*
* Copyright (c) 2024 IMProject Development Team. All rights reserved.
* Authors: Juraj Ciberlin <[email protected]>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name IMProject nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* 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 OWNER 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.
*
****************************************************************************/

#include "vernam_cipher.h"

#include <string.h>

#include "utils.h"

#define UPPER_A_ASCII (65)
#define LOWER_A_ASCII (97)
#define NUM_OF_ALPHA (26)

bool
VernamCipher_encrypt(char* msg, const char* key, int32_t key_length) {
bool status = false;
const size_t msg_length = strlen(msg);
if ((int32_t)msg_length == key_length) {
for (int32_t i = 0; i < key_length; ++i) {
if (Utils_isAlpha(msg[i])) {
int8_t c;
if (Utils_isLowerChar(key[i])) {
c = LOWER_A_ASCII;
} else {
c = UPPER_A_ASCII;
}

int32_t ascii_val;
if (Utils_isUpperChar(msg[i])) {
ascii_val = UPPER_A_ASCII;
} else {
ascii_val = LOWER_A_ASCII;
}

int32_t temp = (((int8_t)msg[i] - ascii_val + (int8_t)key[i] - c) % NUM_OF_ALPHA);
int32_t cipher = temp + ascii_val;
msg[i] = (char)cipher;
}
}
status = true;
}
return status;
}

bool
VernamCipher_decrypt(char* msg, const char* key, int32_t key_length) {
bool status = false;
const size_t msg_length = strlen(msg);
if ((int32_t)msg_length == key_length) {
for (int32_t i = 0; i < key_length; ++i) {
if (Utils_isAlpha(msg[i])) {
int8_t c;
if (Utils_isLowerChar(key[i])) {
c = LOWER_A_ASCII;
} else {
c = UPPER_A_ASCII;
}

int32_t ascii_val;
if (Utils_isUpperChar(msg[i])) {
ascii_val = UPPER_A_ASCII;
} else {
ascii_val = LOWER_A_ASCII;
}

int32_t cipher = ((msg[i] - ascii_val) - (key[i] - c));
cipher = (cipher < 0) ? (cipher + NUM_OF_ALPHA + ascii_val) : (cipher + ascii_val);
msg[i] = (char)cipher;
}
}
status = true;
}
return status;
}
1 change: 1 addition & 0 deletions Tests/test_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ RunAllTests(void) {
RUN_TEST_GROUP(Scheduler);
RUN_TEST_GROUP(SelectionSort);
RUN_TEST_GROUP(Utils);
RUN_TEST_GROUP(VernamCipher);
}

int
Expand Down
35 changes: 35 additions & 0 deletions Tests/test_vernam_cipher.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include "vernam_cipher.h"

#include <string.h>

#include "unity.h"
#include "unity_fixture.h"

TEST_GROUP(VernamCipher);

TEST_SETUP(VernamCipher) {
}

TEST_TEAR_DOWN(VernamCipher) {
}

TEST_GROUP_RUNNER(VernamCipher) {
RUN_TEST_CASE(VernamCipher, VernamCipher_encryptDecrypt);
}

TEST(VernamCipher, VernamCipher_encryptDecrypt) {
const char expected_result[] = "ReSuLt1a";
const char key1[] = "OSIJEK11";
const char key2[] = "OSijek!/";
char message[] = "ReSuLt1a";
TEST_ASSERT_TRUE(VernamCipher_encrypt(message, key1, (int32_t)strlen(key1)));
TEST_ASSERT_TRUE(VernamCipher_decrypt(message, key1, (int32_t)strlen(key1)));
TEST_ASSERT_EQUAL_STRING(expected_result, message);

TEST_ASSERT_TRUE(VernamCipher_encrypt(message, key2, (int32_t)strlen(key2)));
TEST_ASSERT_TRUE(VernamCipher_decrypt(message, key2, (int32_t)strlen(key2)));
TEST_ASSERT_EQUAL_STRING(expected_result, message);

TEST_ASSERT_FALSE(VernamCipher_encrypt(message, key1, 3));
TEST_ASSERT_FALSE(VernamCipher_decrypt(message, key1, 100));
}

0 comments on commit 395590f

Please sign in to comment.