-
Notifications
You must be signed in to change notification settings - Fork 48
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Finished implementation of encode and decode #94
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
hi |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
hi this is a secret | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
/********************************************************************* | ||
* Filename: arcfour.c | ||
* Author: Brad Conte (brad AT bradconte.com) | ||
* Copyright: | ||
* Disclaimer: This code is presented "as is" without any guarantees. | ||
* Details: Implementation of the ARCFOUR encryption algorithm. | ||
Algorithm specification can be found here: | ||
* http://en.wikipedia.org/wiki/RC4 | ||
*********************************************************************/ | ||
|
||
/*************************** HEADER FILES ***************************/ | ||
#include "arcfour.h" | ||
#include "kernel/types.h" | ||
#include "kernel/stat.h" | ||
#include "user/user.h" | ||
|
||
/*********************** FUNCTION DEFINITIONS ***********************/ | ||
void arcfour_key_setup(BYTE state[], const BYTE key[], int len) | ||
{ | ||
int i, j; | ||
BYTE t; | ||
|
||
for (i = 0; i < 256; ++i) | ||
state[i] = i; | ||
for (i = 0, j = 0; i < 256; ++i) { | ||
j = (j + state[i] + key[i % len]) % 256; | ||
t = state[i]; | ||
state[i] = state[j]; | ||
state[j] = t; | ||
} | ||
} | ||
|
||
// This does not hold state between calls. It always generates the | ||
// stream starting from the first output byte. | ||
void arcfour_generate_stream(BYTE state[], BYTE out[], size_t len) | ||
{ | ||
int i, j; | ||
size_t idx; | ||
BYTE t; | ||
|
||
for (idx = 0, i = 0, j = 0; idx < len; ++idx) { | ||
i = (i + 1) % 256; | ||
j = (j + state[i]) % 256; | ||
t = state[i]; | ||
state[i] = state[j]; | ||
state[j] = t; | ||
out[idx] = state[(state[i] + state[j]) % 256]; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/********************************************************************* | ||
* Filename: arcfour.h | ||
* Author: Brad Conte (brad AT bradconte.com) | ||
* Copyright: | ||
* Disclaimer: This code is presented "as is" without any guarantees. | ||
* Details: Defines the API for the corresponding ARCFOUR implementation. | ||
*********************************************************************/ | ||
|
||
#ifndef ARCFOUR_H | ||
#define ARCFOUR_H | ||
|
||
/*************************** HEADER FILES ***************************/ | ||
#include <stddef.h> | ||
|
||
/**************************** DATA TYPES ****************************/ | ||
typedef unsigned char BYTE; // 8-bit byte | ||
|
||
/*********************** FUNCTION DECLARATIONS **********************/ | ||
// Input: state - the state used to generate the keystream | ||
// key - Key to use to initialize the state | ||
// len - length of key in bytes (valid lenth is 1 to 256) | ||
void arcfour_key_setup(BYTE state[], const BYTE key[], int len); | ||
|
||
// Pseudo-Random Generator Algorithm | ||
// Input: state - the state used to generate the keystream | ||
// out - Must be allocated to be of at least "len" length | ||
// len - number of bytes to generate | ||
void arcfour_generate_stream(BYTE state[], BYTE out[], size_t len); | ||
|
||
#endif // ARCFOUR_H |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
/********************************************************************* | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Great documentation! |
||
* Filename: base64.c | ||
* Author: Brad Conte (brad AT bradconte.com) | ||
* Copyright: | ||
* Disclaimer: This code is presented "as is" without any guarantees. | ||
* Details: Implementation of the Base64 encoding algorithm. | ||
*********************************************************************/ | ||
|
||
/*************************** HEADER FILES ***************************/ | ||
//#include <stdlib.h> | ||
#include "base64.h" | ||
#include "kernel/types.h" | ||
#include "kernel/stat.h" | ||
#include "user/user.h" | ||
/****************************** MACROS ******************************/ | ||
#define NEWLINE_INVL 76 | ||
|
||
/**************************** VARIABLES *****************************/ | ||
// Note: To change the charset to a URL encoding, replace the '+' and '/' with '*' and '-' | ||
static const BYTE charset[]={"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"}; | ||
|
||
/*********************** FUNCTION DEFINITIONS ***********************/ | ||
BYTE revchar(char ch) | ||
{ | ||
if (ch >= 'A' && ch <= 'Z') | ||
ch -= 'A'; | ||
else if (ch >= 'a' && ch <='z') | ||
ch = ch - 'a' + 26; | ||
else if (ch >= '0' && ch <='9') | ||
ch = ch - '0' + 52; | ||
else if (ch == '+') | ||
ch = 62; | ||
else if (ch == '/') | ||
ch = 63; | ||
|
||
return(ch); | ||
} | ||
|
||
size_t base64_encode(const BYTE in[], BYTE out[], size_t len, int newline_flag) | ||
{ | ||
size_t idx, idx2, blks, blk_ceiling, left_over, newline_count = 0; | ||
|
||
blks = (len / 3); | ||
left_over = len % 3; | ||
|
||
if (out == NULL) { | ||
idx2 = blks * 4 ; | ||
if (left_over) | ||
idx2 += 4; | ||
if (newline_flag) | ||
idx2 += len / 57; // (NEWLINE_INVL / 4) * 3 = 57. One newline per 57 input bytes. | ||
} | ||
else { | ||
// Since 3 input bytes = 4 output bytes, determine out how many even sets of | ||
// 3 bytes the input has. | ||
blk_ceiling = blks * 3; | ||
for (idx = 0, idx2 = 0; idx < blk_ceiling; idx += 3, idx2 += 4) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Really interesting logic! |
||
out[idx2] = charset[in[idx] >> 2]; | ||
out[idx2 + 1] = charset[((in[idx] & 0x03) << 4) | (in[idx + 1] >> 4)]; | ||
out[idx2 + 2] = charset[((in[idx + 1] & 0x0f) << 2) | (in[idx + 2] >> 6)]; | ||
out[idx2 + 3] = charset[in[idx + 2] & 0x3F]; | ||
// The offical standard requires a newline every 76 characters. | ||
// (Eg, first newline is character 77 of the output.) | ||
if (((idx2 - newline_count + 4) % NEWLINE_INVL == 0) && newline_flag) { | ||
out[idx2 + 4] = '\n'; | ||
idx2++; | ||
newline_count++; | ||
} | ||
} | ||
|
||
if (left_over == 1) { | ||
out[idx2] = charset[in[idx] >> 2]; | ||
out[idx2 + 1] = charset[(in[idx] & 0x03) << 4]; | ||
out[idx2 + 2] = '='; | ||
out[idx2 + 3] = '='; | ||
idx2 += 4; | ||
} | ||
else if (left_over == 2) { | ||
out[idx2] = charset[in[idx] >> 2]; | ||
out[idx2 + 1] = charset[((in[idx] & 0x03) << 4) | (in[idx + 1] >> 4)]; | ||
out[idx2 + 2] = charset[(in[idx + 1] & 0x0F) << 2]; | ||
out[idx2 + 3] = '='; | ||
idx2 += 4; | ||
} | ||
} | ||
|
||
return(idx2); | ||
} | ||
|
||
size_t base64_decode(const BYTE in[], BYTE out[], size_t len) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Appreciate how many functions you have. Very maintainable and readable code! |
||
{ | ||
//BYTE ch; | ||
size_t idx, idx2, blks, blk_ceiling, left_over; | ||
|
||
if (in[len - 1] == '=') | ||
len--; | ||
if (in[len - 1] == '=') | ||
len--; | ||
|
||
blks = len / 4; | ||
left_over = len % 4; | ||
|
||
if (out == NULL) { | ||
if (len >= 77 && in[NEWLINE_INVL] == '\n') // Verify that newlines where used. | ||
len -= len / (NEWLINE_INVL + 1); | ||
blks = len / 4; | ||
left_over = len % 4; | ||
|
||
idx = blks * 3; | ||
if (left_over == 2) | ||
idx ++; | ||
else if (left_over == 3) | ||
idx += 2; | ||
} | ||
else { | ||
blk_ceiling = blks * 4; | ||
for (idx = 0, idx2 = 0; idx2 < blk_ceiling; idx += 3, idx2 += 4) { | ||
if (in[idx2] == '\n') | ||
idx2++; | ||
out[idx] = (revchar(in[idx2]) << 2) | ((revchar(in[idx2 + 1]) & 0x30) >> 4); | ||
out[idx + 1] = (revchar(in[idx2 + 1]) << 4) | (revchar(in[idx2 + 2]) >> 2); | ||
out[idx + 2] = (revchar(in[idx2 + 2]) << 6) | revchar(in[idx2 + 3]); | ||
} | ||
|
||
if (left_over == 2) { | ||
out[idx] = (revchar(in[idx2]) << 2) | ((revchar(in[idx2 + 1]) & 0x30) >> 4); | ||
idx++; | ||
} | ||
else if (left_over == 3) { | ||
out[idx] = (revchar(in[idx2]) << 2) | ((revchar(in[idx2 + 1]) & 0x30) >> 4); | ||
out[idx + 1] = (revchar(in[idx2 + 1]) << 4) | (revchar(in[idx2 + 2]) >> 2); | ||
idx += 2; | ||
} | ||
} | ||
|
||
return(idx); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
/********************************************************************* | ||
* Filename: base64.h | ||
* Author: Brad Conte (brad AT bradconte.com) | ||
* Copyright: | ||
* Disclaimer: This code is presented "as is" without any guarantees. | ||
* Details: Defines the API for the corresponding Base64 implementation. | ||
*********************************************************************/ | ||
|
||
#ifndef BASE64_H | ||
#define BASE64_H | ||
|
||
/*************************** HEADER FILES ***************************/ | ||
#include <stddef.h> | ||
|
||
/**************************** DATA TYPES ****************************/ | ||
typedef unsigned char BYTE; // 8-bit byte | ||
|
||
/*********************** FUNCTION DECLARATIONS **********************/ | ||
// Returns the size of the output. If called with out = NULL, will just return | ||
// the size of what the output would have been (without a terminating NULL). | ||
size_t base64_encode(const BYTE in[], BYTE out[], size_t len, int newline_flag); | ||
|
||
// Returns the size of the output. If called with out = NULL, will just return | ||
// the size of what the output would have been (without a terminating NULL). | ||
size_t base64_decode(const BYTE in[], BYTE out[], size_t len); | ||
|
||
#endif // BASE64_H |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
#include "base64.h" | ||
#include "arcfour.h" | ||
#include "kernel/types.h" | ||
#include "kernel/stat.h" | ||
#include "user/user.h" | ||
#include "kernel/fcntl.h" | ||
|
||
/** | ||
* This function reads Base64 encoded data from the specified file descriptor in chunks, decodes it back to its original form, and | ||
* prints the decoded content to the console with its size. | ||
* | ||
* @param fd The file descriptor from which the encoded content is read | ||
* | ||
*/ | ||
void | ||
b64_decode(int fd) | ||
{ | ||
unsigned char buffer[1024]; | ||
unsigned char result[1024]; | ||
int n; | ||
|
||
while ((n = read(fd, buffer, 1024)) > 0) { | ||
int size = base64_decode(buffer, result, n); | ||
printf("Your decoded secret is %s of size %d", result, size); | ||
} | ||
printf("\n"); | ||
} | ||
|
||
/** | ||
* This function reads command-line arguments to determine whether the arguments invoke the Base64 decoding function. | ||
* It processes the specified input file accordingly. | ||
* | ||
* @param argc The number of command-line arguments | ||
* @param argv The command-line arguments | ||
* @return This function prints an error message and exits or closes and exits | ||
* | ||
*/ | ||
int | ||
main(int argc, char *argv[]) | ||
{ | ||
char *crypto_option = argv[1]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here if where you could probably add something for the edge case I brought up in the final comment, or maybe in the decode logic you could have some kind of flag in the file that you check so they always decode in the same format |
||
char *file_name = argv[2]; | ||
|
||
int fd = open(file_name, O_RDONLY); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice edge case checking! |
||
if (fd < 0) { | ||
printf("ERROR, could not open the file %s\n", file_name); | ||
exit(1); | ||
} | ||
|
||
if (strcmp(crypto_option, "-b") == 0) { | ||
b64_decode(fd); | ||
} | ||
|
||
close(fd); | ||
exit(1); | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for adding in these test files! Made it super easy to make sure your code works.