SWE-350 TOTP Generator Milestone 5
The DE-10 board has six 7-segment displays, this can be used to display and generate a time based one-time pin (TOTP).
Loading...
Searching...
No Matches
randomKey.c
Go to the documentation of this file.
1// //
2// // Created by Erick Grant on 10/26/24.
3// //
4//
5
6#include "randomKey.h"
7
8#include <ctype.h>
9#include <stdint.h>
10#include <stdio.h>
11#include <string.h>
12#include <time.h>
13#include <assert.h>
14//#include <_stdlib.h> // This may need to be disabled before ARM execution
15//#include <_stdlib.h>
16//#include <sys/_types/_size_t.h>
17
18
19// Base32 Encoding Table as per RFC 3548
20//static const char base32_encoding_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
21
22// Function to generate a random string
23// https://codereview.stackexchange.com/questions/29198/random-string-generator-in-c
29static char *rand_string(char *str, size_t size)
30{
31 const char charset[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
32
33
34 // Taking current time as seed
35 unsigned int seed = time(0);
36 for (int i = 0; i < size ; i++) {
37
38
39 int rd_num = rand_r(&seed) % (strlen(charset) - 1); // GPT replacement
40 // printf("%d ", rd_num);
41
42 str[i] = charset[rd_num];
43 // printf(" %d-%c ", rd_num, str[i]);
44 }
45
46
47 // printf("\n%s\n", str);
48 return str;
49}
57int get_base32_value(char letter) {
58 // Define the Base32 alphabet according to RFC 4648
59 const char base32_alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
60
61 // Create a lookup table where each index maps to the Base32 value.
62 int lookup[256] = {0}; // Initialize all values to 0.
63
64 // Fill the lookup table with values for each character in the Base32 alphabet
65 for (int i = 0; i < 32; i++) {
66 lookup[(int)base32_alphabet[i]] = i;
67 }
68
69 // Return the value from the lookup table for the given letter
70 return lookup[(int)letter];
71}
72
73
74
82void generateStringKey(char* keyString, int length) {
83 // https://stackoverflow.com/questions/16348512/getting-the-first-10-characters-of-a-string
84 char randomKeyLong[length + 2]; // Protection system, ensuring will always be at least 32 characters, just in case.
85 char* ranKeyLPtr = randomKeyLong; // Make a pointer to the randomKeyLong string
86
87 rand_string(ranKeyLPtr, length + 2); // generate 34 length key
88 strncpy(keyString, randomKeyLong, length); // shorten to 32 characters
89 keyString[length] = 0; // null terminate destination
90
91 // Output the key, delete these lines in a production environment
92 // printf("Random %d-character string: %s\n", length, keyString); // Output the key
93 printf("otpauth://totp/ErickGrant:Milestone?secret=%s\n",keyString); // Output the key as a URL for a totp QR code
94
95
96}
97
98// Base32 character set
99static const char base32_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
100
101// Function to get the Base32 value of a character
102int get_base32_value2(char c) {
103 const char *ptr = strchr(base32_chars, toupper(c));
104 if (ptr) {
105 return ptr - base32_chars;
106 }
107 return -1; // Invalid character
108}
109
110// Function to decode a Base32 string into a byte array
111// Function to decode a Base32 string into a byte array
112// Chatgpt cleaned up and added documentation for this. Nov 30, 2024, Query "Can you make this more documented? Use Doxygen too ..." + code
128uint8_t* base32_decode2(const char* input, size_t* output_len) {
129 size_t input_len = strlen(input);
130 size_t buffer_size = (input_len * 5) / 8; // Each Base32 character encodes 5 bits
131
132 uint8_t* output = (uint8_t*)malloc(buffer_size);
133 if (output == NULL) {
134 printf("Memory allocation failed\n");
135 return NULL;
136 }
137
138 int bits = 0, value = 0, index = 0;
139 for (size_t i = 0; i < input_len; i++) {
140 int digit = get_base32_value2(input[i]);
141 if (digit == -1) {
142 printf("Invalid Base32 character: %c\n", input[i]);
143 free(output);
144 return NULL;
145 }
146
147 value = (value << 5) | digit; // Accumulate 5 bits
148 bits += 5;
149
150 // Extract a byte when we have at least 8 bits
151 if (bits >= 8) {
152 bits -= 8;
153 output[index++] = (value >> bits) & 0xFF;
154 }
155 }
156
157 *output_len = index; // Set the actual length of the output array
158 return output;
159}
160
161
162// Function to clone a uint8_t array
176uint8_t* cloneArray(const uint8_t* original, size_t length) {
177 // Allocate memory for the new array
178 uint8_t* clone = (uint8_t*)malloc(length * sizeof(uint8_t));
179 if (clone == NULL) {
180 printf("Memory allocation failed\n");
181 return NULL; // Return NULL if memory allocation fails
182 }
183
184 // Copy the contents from the original array to the new array
185 memcpy(clone, original, length * sizeof(uint8_t));
186 return clone;
187}
188
189
190
191
192// ChatGPT Generated, Dec 1, 2024
194 // Valid Base32 characters
195 assert(get_base32_value('A') == 0);
196 assert(get_base32_value('B') == 1);
197 assert(get_base32_value('C') == 2);
198 assert(get_base32_value('Z') == 25);
199 assert(get_base32_value('2') == 26);
200 assert(get_base32_value('7') == 31);
201
202 // Invalid characters
203 assert(get_base32_value('1') == NULL); // Not in Base32 alphabet
204 assert(get_base32_value('*') == NULL); // Not in Base32 alphabet
205 assert(get_base32_value('a') == NULL); // Lowercase not supported
206 assert(get_base32_value(' ') == NULL); // Space is invalid
207}
208
211// test_base32_decode();
212 return 1;
213 }
size_t output_len
The length of the uint_8 key in bytes.
Definition main.c:126
int testRandomKey()
Definition randomKey.c:209
void test_get_base32_value()
Definition randomKey.c:193
int get_base32_value2(char c)
Definition randomKey.c:102
uint8_t * base32_decode2(const char *input, size_t *output_len)
Decodes a Base32-encoded string into a binary byte array.
Definition randomKey.c:128
void generateStringKey(char *keyString, int length)
Generates a full string of random characters.
Definition randomKey.c:82
int get_base32_value(char letter)
Returns the int value (1-32) of a character.
Definition randomKey.c:57
uint8_t * cloneArray(const uint8_t *original, size_t length)
Function to clone a uint8_t array.
Definition randomKey.c:176