LCOV - code coverage report
Current view: top level - modules/nt - rc4.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 67 67 100.0 %
Date: 2024-05-13 05:06:06 Functions: 7 7 100.0 %
Legend: Lines: hit not hit

          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             : }

Generated by: LCOV version 1.14