Line data Source code
1 : /*************************************************************************
2 : *
3 : * Project
4 : * _____ _____ __ __ _____
5 : * / ____| __ \| \/ | __ \
6 : * ___ _ __ ___ _ __ | | __| |__) | \ / | |__) |
7 : * / _ \| '_ \ / _ \ '_ \| | |_ | ___/| |\/| | ___/
8 : *| (_) | |_) | __/ | | | |__| | | | | | | |
9 : * \___/| .__/ \___|_| |_|\_____|_| |_| |_|_|
10 : * | |
11 : * |_|
12 : *
13 : * Copyright (C) Akiel Aries, <akiel@akiel.org>, et al.
14 : *
15 : * This software is licensed as described in the file LICENSE, which
16 : * you should have received as part of this distribution. The terms
17 : * among other details are referenced in the official documentation
18 : * seen here : https://akielaries.github.io/openGPMP/ along with
19 : * important files seen in this project.
20 : *
21 : * You may opt to use, copy, modify, merge, publish, distribute
22 : * and/or sell copies of the Software, and permit persons to whom
23 : * the Software is furnished to do so, under the terms of the
24 : * LICENSE file. As this is an Open Source effort, all implementations
25 : * must be of the same methodology.
26 : *
27 : *
28 : *
29 : * This software is distributed on an AS IS basis, WITHOUT
30 : * WARRANTY OF ANY KIND, either express or implied.
31 : *
32 : ************************************************************************/
33 :
34 : /*
35 : * This file shows the implementation of the Rivest Cipher 4 (RC4)
36 : * encryption algorithm created by Ron Rivest using either a
37 : * traditional swap method or with the XOR operator
38 : */
39 : #include <cmath>
40 : #include <cstdlib>
41 : #include <iostream>
42 : #include <openGPMP/nt/rc4.hpp>
43 : #include <sstream>
44 : #include <stdio.h>
45 : #include <stdlib.h>
46 : #include <string.h>
47 : #include <string>
48 :
49 796 : void gpmp::RC4::byte_swap(uint8_t *a, uint8_t *b) {
50 796 : uint8_t swapped = *a;
51 796 : swapped = *a;
52 796 : *a = *b;
53 796 : *b = swapped;
54 796 : }
55 :
56 796 : void gpmp::RC4::trad_swap(unsigned char *a, unsigned char *b) {
57 796 : int swapped = *a;
58 796 : *a = *b;
59 796 : *b = swapped;
60 796 : }
61 :
62 796 : void gpmp::RC4::XOR_swap(unsigned char *a, unsigned char *b) {
63 796 : *a ^= *b;
64 796 : *b ^= *a;
65 796 : *a ^= *b;
66 796 : }
67 :
68 9 : void gpmp::RC4::KSA(char *key, unsigned char *S, int swap_type) {
69 9 : uint32_t len = strlen(key);
70 9 : int j = 0;
71 :
72 2313 : for (int i = 0; i < BYTE_LIMIT; i++) {
73 2304 : S[i] = i;
74 : }
75 :
76 2313 : for (int i = 0; i < BYTE_LIMIT; i++) {
77 2304 : j = (j + S[i] + key[i % len]) & BITS;
78 :
79 : // choose swap algorithm based off swap_type
80 2304 : if (swap_type == 0) {
81 768 : XOR_swap(&S[i], &S[j]);
82 1536 : } else if (swap_type == 1) {
83 768 : trad_swap(&S[i], &S[j]);
84 768 : } else if (swap_type == 2) {
85 768 : byte_swap(&S[i], &S[j]);
86 : }
87 : }
88 9 : }
89 :
90 9 : void gpmp::RC4::PRGA(unsigned char *S,
91 : char *plaintext,
92 : unsigned char *ciphertext,
93 : int swap_type) {
94 9 : int i = 0;
95 9 : int j = 0;
96 :
97 93 : for (size_t n = 0, len = strlen(plaintext); n < len; n++) {
98 84 : i = (i + 1) & BITS;
99 84 : j = (j + S[i]) & BITS;
100 :
101 : // choose swap algorithm based off swap_type
102 84 : if (swap_type == 0) {
103 28 : XOR_swap(&S[i], &S[j]);
104 56 : } else if (swap_type == 1) {
105 28 : trad_swap(&S[i], &S[j]);
106 28 : } else if (swap_type == 2) {
107 28 : byte_swap(&S[i], &S[j]);
108 : }
109 :
110 84 : uint32_t rnd = S[(S[i] + S[j]) & BITS];
111 :
112 84 : ciphertext[n] = rnd ^ plaintext[n];
113 : }
114 9 : }
115 :
116 : std::string
117 9 : gpmp::RC4::store_hash(char *plaintext, unsigned char *hashtext, int swap_type) {
118 : // length of our plaintext
119 9 : size_t len = strlen((char *)plaintext);
120 : // for snprintf declare a buffer
121 9 : char buffer[len + 1];
122 9 : size_t size = sizeof(buffer);
123 :
124 : // initialize empty string
125 9 : std::string stored_text = "";
126 :
127 : // traverse the hashtext appending each block to a string
128 93 : for (size_t index = 0; index < len; index++) {
129 84 : if (swap_type == 0) {
130 28 : snprintf(buffer, size, "|x%02hhx|", hashtext[index]);
131 : }
132 : // to format our hash to a string for future manipulation
133 : else {
134 56 : snprintf(buffer, size, "%02hhX", hashtext[index]);
135 : }
136 : // append the declared string
137 84 : stored_text += std::string(buffer);
138 : }
139 18 : return stored_text;
140 9 : }
141 :
142 15 : unsigned char *gpmp::RC4::compute(char *key,
143 : char *plaintext,
144 : unsigned char *ciphertext,
145 : int swap_type) {
146 15 : if (ciphertext == NULL) {
147 2 : throw std::runtime_error("[-] Error Allocating Memory");
148 : }
149 :
150 : // check for swap types 1-3
151 13 : if (0 <= swap_type && swap_type <= 2) {
152 : unsigned char S[BYTE_LIMIT];
153 9 : KSA(key, S, swap_type);
154 9 : PRGA(S, plaintext, ciphertext, swap_type);
155 9 : }
156 :
157 4 : else if (swap_type > 2) {
158 4 : throw std::runtime_error("[-] Invalid swap_type");
159 : }
160 :
161 9 : return ciphertext;
162 : }
|