From 83572733c4dfb567bee38b3c651229c3e039b289 Mon Sep 17 00:00:00 2001 From: miha-q <> Date: Tue, 8 Aug 2023 22:42:04 -0400 Subject: [PATCH] Tue Aug 8 10:42:04 PM EDT 2023 --- bin/CryptoFoleo.h | 39 ++-- bin/libCryptoFoleo.so | Bin 35608 -> 36200 bytes bin/test | Bin 40952 -> 45376 bytes build.sh | 2 + private.key | 28 +++ public.key | 15 ++ src/headers.h | 9 +- src/prigen.c | 28 +-- src/rsa.c | 425 ++++++++++++++++++++++++++++++++++++++---- tests/test.c | 64 +++++-- 10 files changed, 523 insertions(+), 87 deletions(-) create mode 100644 private.key create mode 100644 public.key diff --git a/bin/CryptoFoleo.h b/bin/CryptoFoleo.h index 9575e5e..a32b714 100644 --- a/bin/CryptoFoleo.h +++ b/bin/CryptoFoleo.h @@ -1,27 +1,28 @@ #include #include -uint8_t* chacha20(uint8_t[32], uint8_t[12], uint32_t, uint64_t); -uint8_t* chacha20_poly1305(uint8_t[32], uint8_t[12], uint8_t*, uint64_t); -uint8_t* dhke(uint8_t*, uint8_t*); -uint8_t* dhke_prf(uint32_t, uint8_t*, uint32_t, uint8_t*, uint32_t, uint8_t*, uint32_t); -uint8_t* poly1305(uint8_t*, uint8_t*, uint8_t*, uint64_t); -uint8_t* prigen(uint16_t); -#define RSA_NONE 99 -#define RSA_ENCRYPTION 1 -#define RSA_SIGNATURE 2 -#define RSA_OAEP 3 -#define RSA_PSS 4 +uint8_t* foleo_chacha20(uint8_t[32], uint8_t[12], uint32_t, uint64_t); +uint8_t* foleo_chacha20_poly1305(uint8_t[32], uint8_t[12], uint8_t*, uint64_t); +uint8_t* foleo_dhke(uint8_t*, uint8_t*); +uint8_t* foleo_dhke_prf(uint32_t, uint8_t*, uint32_t, uint8_t*, uint32_t, uint8_t*, uint32_t); +uint8_t* foleo_poly1305(uint8_t*, uint8_t*, uint8_t*, uint64_t); +static uint8_t* foleo_prigen(uint16_t); +#define FOLEO_RSA_NONE 99 +#define FOLEO_RSA_ENCRYPTION 1 +#define FOLEO_RSA_SIGNATURE 2 +#define FOLEO_RSA_OAEP 3 +#define FOLEO_RSA_PSS 4 typedef struct { mpz_t n, k; uint16_t bitWidth; } rsakey_t; -rsakey_t rsa_public(uint8_t*, uint16_t, uint8_t*, uint16_t, uint8_t*, uint16_t); -rsakey_t rsa_private(uint8_t*, uint16_t, uint8_t*, uint16_t, uint8_t*, uint16_t); -rsakey_t rsa_import(uint8_t*, uint16_t, uint8_t*, uint16_t); -uint8_t* rsa_export(rsakey_t, uint8_t, uint16_t*); -void rsa_free(rsakey_t); -uint8_t* rsa_encrypt(rsakey_t, uint8_t, uint8_t*, uint16_t); -uint8_t* rsa_decrypt(rsakey_t, uint8_t, uint8_t*, uint16_t*); -uint8_t* sha256(uint8_t*, uint32_t); +rsakey_t foleo_rsa_public(uint8_t*, uint16_t, uint8_t*, uint16_t, uint8_t*, uint16_t); +rsakey_t foleo_rsa_private(uint8_t*, uint16_t, uint8_t*, uint16_t, uint8_t*, uint16_t); +rsakey_t foleo_rsa_import(uint8_t*, uint16_t, uint8_t*, uint16_t); +uint8_t* foleo_rsa_export(rsakey_t, uint8_t, uint16_t*); +void foleo_rsa_free(rsakey_t); +uint8_t* foleo_rsa_encrypt(rsakey_t, uint8_t, uint8_t*, uint16_t); +uint8_t* foleo_rsa_decrypt(rsakey_t, uint8_t, uint8_t*, uint16_t*); +uint8_t* foleo_sha256(uint8_t*, uint32_t); +#define FOLEO_SHA256 foleo_sha256, 32, 64 diff --git a/bin/libCryptoFoleo.so b/bin/libCryptoFoleo.so index ed3cbcee1614592813d55651395f604d3072b5df..6b353e5008bbfd89c16c59c3e5cb38d58802dde2 100755 GIT binary patch delta 12879 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Ñ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 AS^xk5 diff --git a/bin/test b/bin/test index 97110b4eca3919ff04c4488e9fc5c511cdfd2e80..88de3ff1f530b7ca43b3bd10c3e9b8a9aff36e3e 100755 GIT binary patch delta 17891 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 delta 11889 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'(!$?#<>)?)s#*":"{#*!)`/}\`| +|e)<&'!@x/&]!x,:x#}%^.;=!%&[ss<.#| +|ss%[`#=~;&?#;}>]);&%,&)##"@=(>,(;;[.,#s&e&}xs*| +|/^){\[.%}x:@#e&e,_@&?}!,*#!"="_%| +|?]#!;%*^(,e^!(()`:?$,(?*=[."#;,?| +|}`#<%,@<=se,;._e&].&~_/~@^xxx#]>| +|<@?/"_^=^{^'({~>=}(>~='%}.$e(_:#| +|^e@s,_[}=(;;?%%&[.`%s"}:s>_x):`e| +|@x'=s$="_,s\~*/.[?%,(&=()x=`=;#&| +|]?{,:~](<~;""}*^?}#^*@'`~*)#``&^| +|'x#>]=x~$@/\s`e*,,)!`}<%? @;"_&&| +|=e>@e<{>ss`xx{;:[,(:}:(,(| +|.?^@<@%`>?^&`(?{'s?~x>e`x~$_(#s'| +|=;]>e/x$@\$:?>{~)'"{(>*"e]}""x=[:=&"[]?)^)*:x/e:~%\[]{_?_~]#| +|''];'%.:*~@s{(_^x*":~}{((^&^)},;| +|.#[*[#?=:#:"`@e}/$%!=\"'s,?%s^`^| +|#\$})?x<(e:%*])@#}~"?/@{!\s%e*![| +|>;<(,%'#{]#*;@<({:!)\(`%}~#?]?')| +|=/e]^!se~@<@_>}/,[`'?/e<<&>&[=s| +|x)&&[>;&.*s*;'=e"{;! | ++--------------------------------+ diff --git a/public.key b/public.key new file mode 100644 index 0000000..5b1a4a2 --- /dev/null +++ b/public.key @@ -0,0 +1,15 @@ ++--------[RSA Public Key]--------+ +|(x({& @;"_&&=e>@e<{>ss`xx| +|{;:[,(:}:(,(.?^@<@%`>?^&`(?{'s?~| +|x>e`x~$_(#s'=;]>e/x$@\$:?>{~)'"{| +|(>*"e]}""x=[:=&"[]?)^)*:x/e:| +|~%\[]{_?_~]#''];'%.:*~@s{(_^x*":| +|~}{((^&^)},;.#[*[#?=:#:"`@e}/$%!| +|=\"'s,?%s^`^#\$})?x<(e:%*])@#}~"| +|?/@{!\s%e*![>;<(,%'#{]#*;@<({:!)| +|\(`%}~#?]?')=/e]^!se~@<@_>}/,[`| +|'?/e<<&>&[=sx)&&[>;&.*s*;'=e"{;!| ++--------------------------------+ diff --git a/src/headers.h b/src/headers.h index 03d65e7..dc6dd2f 100644 --- a/src/headers.h +++ b/src/headers.h @@ -6,7 +6,7 @@ uint8_t* foleo_chacha20_poly1305(uint8_t[32], uint8_t[12], uint8_t*, uint64_t); uint8_t* foleo_dhke(uint8_t*, uint8_t*); uint8_t* foleo_dhke_prf(uint32_t, uint8_t*, uint32_t, uint8_t*, uint32_t, uint8_t*, uint32_t); uint8_t* foleo_poly1305(uint8_t*, uint8_t*, uint8_t*, uint64_t); -uint8_t* foleo_prigen(uint16_t); +static uint8_t* foleo_prigen(uint16_t); #define FOLEO_RSA_NONE 99 #define FOLEO_RSA_ENCRYPTION 1 #define FOLEO_RSA_SIGNATURE 2 @@ -15,14 +15,15 @@ uint8_t* foleo_prigen(uint16_t); typedef struct { mpz_t n, k; + uint8_t* label; uint16_t bitWidth; } rsakey_t; rsakey_t foleo_rsa_public(uint8_t*, uint16_t, uint8_t*, uint16_t, uint8_t*, uint16_t); rsakey_t foleo_rsa_private(uint8_t*, uint16_t, uint8_t*, uint16_t, uint8_t*, uint16_t); -rsakey_t foleo_rsa_import(uint8_t*, uint16_t, uint8_t*, uint16_t); -uint8_t* foleo_rsa_export(rsakey_t, uint8_t, uint16_t*); +//rsakey_t foleo_rsa_import(uint8_t*, uint16_t, uint8_t*, uint16_t); +//uint8_t* foleo_rsa_export(rsakey_t, uint8_t, uint16_t*); void foleo_rsa_free(rsakey_t); uint8_t* foleo_rsa_encrypt(rsakey_t, uint8_t, uint8_t*, uint16_t); uint8_t* foleo_rsa_decrypt(rsakey_t, uint8_t, uint8_t*, uint16_t*); uint8_t* foleo_sha256(uint8_t*, uint32_t); -#define FOLEO_SHA256_PARAMETERS foleo_sha256, 32, 64 +#define FOLEO_SHA256 foleo_sha256, 32, 64 diff --git a/src/prigen.c b/src/prigen.c index 31ac240..a78187e 100644 --- a/src/prigen.c +++ b/src/prigen.c @@ -1,11 +1,11 @@ -#ifndef __PRIGEN__ -#define __PRIGEN__ +#ifndef __FOLEO_PRIGEN__ +#define __FOLEO_PRIGEN__ #include #include #include #include -static void PRIGEN_GetRandom(mpz_t n, uint16_t bytes, FILE *f) +static void FOLEO_PRIGEN_GetRandom(mpz_t n, uint16_t bytes, FILE *f) { mpz_set_ui(n, 0); for (uint16_t i = 0; i < bytes; i++) @@ -18,7 +18,7 @@ static void PRIGEN_GetRandom(mpz_t n, uint16_t bytes, FILE *f) } } -static void PRIGEN_ComputeDS(mpz_t n, mpz_t d, uint16_t *s) +static void FOLEO_PRIGEN_ComputeDS(mpz_t n, mpz_t d, uint16_t *s) { mpz_t t; mpz_init(t); @@ -35,7 +35,7 @@ static void PRIGEN_ComputeDS(mpz_t n, mpz_t d, uint16_t *s) mpz_clear(t); } -static uint8_t PRIGEN_PrimeTestOnce(mpz_t n, mpz_t d, uint16_t s, uint16_t witness) +static uint8_t FOLEO_PRIGEN_PrimeTestOnce(mpz_t n, mpz_t d, uint16_t s, uint16_t witness) { mpz_t x, m, a, two; uint8_t ret = 0; @@ -81,16 +81,16 @@ static uint8_t PRIGEN_PrimeTestOnce(mpz_t n, mpz_t d, uint16_t s, uint16_t witne return ret; } -static uint8_t PRIGEN_PrimeTest(mpz_t n) +static uint8_t FOLEO_PRIGEN_PrimeTest(mpz_t n) { mpz_t d; mpz_init(d); uint16_t s = 0; - PRIGEN_ComputeDS(n, d, &s); + FOLEO_PRIGEN_ComputeDS(n, d, &s); for (uint8_t a = 2; a < 12; a++) { - if (!PRIGEN_PrimeTestOnce(n, d, s, a)) + if (!FOLEO_PRIGEN_PrimeTestOnce(n, d, s, a)) { mpz_clear(d); return 0; @@ -101,18 +101,18 @@ static uint8_t PRIGEN_PrimeTest(mpz_t n) return 1; } -static void PRIGEN_GeneratePrime(mpz_t n, int bytes) +static void FOLEO_PRIGEN_GeneratePrime(mpz_t n, int bytes) { FILE *f = fopen(DEVICE, "r"); do { - PRIGEN_GetRandom(n, bytes, f); - } while (!PRIGEN_PrimeTest(n)); + FOLEO_PRIGEN_GetRandom(n, bytes, f); + } while (!FOLEO_PRIGEN_PrimeTest(n)); fclose(f); } /* Generate prime of X bytes */ -uint8_t* foleo_prigen(uint16_t bytes) +static uint8_t* foleo_prigen(uint16_t bytes) { uint8_t* buffer = malloc(bytes); FILE *f = fopen(DEVICE, "r"); @@ -120,8 +120,8 @@ uint8_t* foleo_prigen(uint16_t bytes) mpz_init(n); do { - PRIGEN_GetRandom(n, bytes, f); - } while (!PRIGEN_PrimeTest(n)); + FOLEO_PRIGEN_GetRandom(n, bytes, f); + } while (!FOLEO_PRIGEN_PrimeTest(n)); mpz_export(buffer, NULL, 1, 1, 0, 0, n); mpz_clear(n); fclose(f); diff --git a/src/rsa.c b/src/rsa.c index 497c918..6c5b8ca 100644 --- a/src/rsa.c +++ b/src/rsa.c @@ -92,42 +92,375 @@ rsakey_t foleo_rsa_private(uint8_t* p, uint16_t pS, uint8_t* q, uint16_t qS, uin return ret; } -uint8_t* foleo_rsa_export(rsakey_t key, uint8_t whichone, uint16_t* newsize) +static uint8_t foleo_rsa_prettymap(uint8_t in, uint8_t dir) { - uint8_t* ret = malloc(key.bitWidth / 8); - switch (whichone) - { - case 'd': - case 'D': - case 'e': - case 'E': - foleo_rsa_store(key.k, ret, key.bitWidth / 8); - *newsize = key.bitWidth / 8; - return ret; - case 'n': - case 'N': - foleo_rsa_store(key.n, ret, key.bitWidth / 8); - *newsize = key.bitWidth / 8; - return ret; - } - *newsize = 0; - free(ret); - return NULL; + if (dir) + { + switch (in) + { + case '_': return 0; + case '!': return 1; + case '@': return 2; + case '#': return 3; + case '$': return 4; + case '%': return 5; + case '^': return 6; + case '&': return 7; + case '*': return 8; + case '(': return 9; + case ')': return 10; + case 's': return 11; + case '~': return 12; + case 'e': return 13; + case '=': return 14; + case '`': return 15; + case '[': return 16; + case ']': return 17; + case '\\': return 18; + case ';': return 19; + case '\'': return 20; + case ',': return 21; + case '.': return 22; + case '/': return 23; + case '{': return 24; + case '}': return 25; + case 'x': return 26; + case ':': return 27; + case '"': return 28; + case '<': return 29; + case '>': return 30; + case '?': return 31; + } + return 0xFF; + } + else + { + switch (in) + { + case 0: return '_'; + case 1: return '!'; + case 2: return '@'; + case 3: return '#'; + case 4: return '$'; + case 5: return '%'; + case 6: return '^'; + case 7: return '&'; + case 8: return '*'; + case 9: return '('; + case 10: return ')'; + case 11: return 's'; + case 12: return '~'; + case 13: return 'e'; + case 14: return '='; + case 15: return '`'; + case 16: return '['; + case 17: return ']'; + case 18: return '\\'; + case 19: return ';'; + case 20: return '\''; + case 21: return ','; + case 22: return '.'; + case 23: return '/'; + case 24: return '{'; + case 25: return '}'; + case 26: return 'x'; + case 27: return ':'; + case 28: return '"'; + case 29: return '<'; + case 30: return '>'; + case 31: return '?'; + } + } } -rsakey_t foleo_rsa_import(uint8_t* bufferK, uint16_t byteSizeK, uint8_t* bufferN, uint16_t byteSizeN) +static rsakey_t foleo_rsa_import(uint8_t* buf) { - rsakey_t ret; - ret.bitWidth = byteSizeN * 8; - mpz_init(ret.k); - mpz_init(ret.n); - mpz_set_ui(ret.k, 0); - mpz_set_ui(ret.n, 0); + rsakey_t k; + mpz_init(k.k); + mpz_init(k.n); + mpz_set_ui(k.k, 0); + mpz_set_ui(k.n, 0); + k.label = malloc(0); + uint32_t lblS = 0; + uint32_t i; + uint8_t state = 0; + uint32_t bitWidth = 0; + for (uint32_t i = 0; buf[i] != 0; i++) + { + if (state == 0) + { + if (buf[i] == '[') state = 1; + if (buf[i] == '\n') state = 2; + } + else if (state == 1) + { + if (buf[i] == ']') + { + state = 2; + k.label = realloc(k.label, lblS + 1); + k.label[lblS] = 0; + } + else + { + k.label = realloc(k.label, lblS + 1); + k.label[lblS++] = buf[i]; + } + } + else if (state == 2) + { + if (buf[i] == ' ') state = 3; + else if (foleo_rsa_prettymap(buf[i], 1) != 0xFF) + { + mpz_mul_ui(k.k, k.k, 32); + mpz_add_ui(k.k, k.k, foleo_rsa_prettymap(buf[i], 1)); + bitWidth += 1; + } + } + else if (state == 3) + { + if (buf[i] == ' ') break; + else if (foleo_rsa_prettymap(buf[i], 1) != 0xFF) + { + mpz_mul_ui(k.n, k.n, 32); + mpz_add_ui(k.n, k.n, foleo_rsa_prettymap(buf[i], 1)); + } + } + } + k.bitWidth = mpz_sizeinbase(k.n, 2); + if (k.bitWidth % 8 != 0) + { + k.bitWidth = (k.bitWidth + 1) % 8 == 0 ? k.bitWidth + 1 : k.bitWidth - 1; + while (k.bitWidth % 8 != 0) k.bitWidth++; + } + return k; +} - foleo_rsa_load(ret.k, bufferK, byteSizeK); - foleo_rsa_load(ret.n, bufferN, byteSizeN); - - return ret; +static uint8_t* foleo_rsa_export(rsakey_t k) +{ + const uint8_t width = 32; + mpz_t n, t; + mpz_init(n); + mpz_init(t); + mpz_set(n, k.n); + uint8_t* kn = malloc(0); + uint16_t knS = 0; + while (mpz_sgn(n) != 0) + { + mpz_mod_ui(t, n, 32); + kn = realloc(kn, knS + 1); + kn[knS++] = foleo_rsa_prettymap(mpz_get_ui(t), 0); + mpz_div_ui(n, n, 32); + } + mpz_set(n, k.k); + uint8_t* kk = malloc(0); + uint16_t kkS = 0; + while (mpz_sgn(n) != 0) + { + mpz_mod_ui(t, n, 32); + kk = realloc(kk, kkS + 1); + kk[kkS++] = foleo_rsa_prettymap(mpz_get_ui(t), 0); + mpz_div_ui(n, n, 32); + } + + uint8_t* keyascii = malloc(0); + uint32_t keyascii_i = 0; + uint32_t cnt = 0; + + uint8_t nolabel = 0; + if (k.label == NULL) + { + nolabel = 1; + } + else if (k.label[0] == 0) + { + nolabel = 1; + } + + keyascii = realloc(keyascii, keyascii_i + 1); + keyascii[keyascii_i++] = '+'; + if (nolabel) + { + for (uint32_t i = 0; i < width; i++) + { + keyascii = realloc(keyascii, keyascii_i + 1); + keyascii[keyascii_i++] = '-'; + } + } + else + { + uint8_t* tmsg = malloc(1); + tmsg[0] = '['; + uint32_t li = 0; + uint32_t mS = 1; + for (;;) + { + tmsg = realloc(tmsg, mS + 1); + tmsg[mS++] = k.label[li++]; + if (k.label[li] == 0 || mS > (width / 3) * 2) + { + tmsg = realloc(tmsg, mS + 2); + tmsg[mS++] = ']'; + break; + } + } + uint32_t m0 = (width / 2) - ((mS - 1) / 2) - 1; + uint32_t m1 = m0 + mS; + for (uint32_t i = 0; i < width; i++) + { + keyascii = realloc(keyascii, keyascii_i + 1); + if (i >= m0 && i < m1) + { + keyascii[keyascii_i++] = tmsg[i - m0]; + } + else + { + keyascii[keyascii_i++] = '-'; + } + } + free(tmsg); + } + keyascii = realloc(keyascii, keyascii_i + 3); + keyascii[keyascii_i++] = '+'; + keyascii[keyascii_i++] = '\n'; + keyascii[keyascii_i++] = '|'; + + for (uint8_t i = 0; i < 2; i++) + { + if (i == 1) + { + keyascii = realloc(keyascii, keyascii_i + 1); + keyascii[keyascii_i++] = ' '; + mpz_set(n, k.n); + cnt++; + if (cnt % width == 0) + { + keyascii = realloc(keyascii, keyascii_i + 3); + keyascii[keyascii_i++] = '|'; + keyascii[keyascii_i++] = '\n'; + keyascii[keyascii_i++] = '|'; + cnt = 0; + } + } + for (uint16_t j = 0; j < (i == 0 ? kkS : knS); j++) + { + keyascii = realloc(keyascii, keyascii_i + 1); + keyascii[keyascii_i++] = i == 0 ? kk[kkS - j - 1] : kn[knS - j - 1]; + cnt++; + if (cnt % width == 0) + { + keyascii = realloc(keyascii, keyascii_i + 3); + keyascii[keyascii_i++] = '|'; + keyascii[keyascii_i++] = '\n'; + keyascii[keyascii_i++] = '|'; + cnt = 0; + } + } + } + free(kn); + free(kk); + mpz_clear(n); + mpz_clear(t); + + if (cnt % width == 0) + { + keyascii[keyascii_i - 1] = '+'; + } + else + { + while (cnt % width != 0) + { + keyascii = realloc(keyascii, keyascii_i + 1); + keyascii[keyascii_i++] = ' '; + cnt++; + } + keyascii = realloc(keyascii, keyascii_i + 3); + keyascii[keyascii_i++] = '|'; + keyascii[keyascii_i++] = '\n'; + keyascii[keyascii_i++] = '+'; + } + for (uint32_t i = 0; i < width; i++) + { + keyascii = realloc(keyascii, keyascii_i + 1); + keyascii[keyascii_i++] = '-'; + } + keyascii = realloc(keyascii, keyascii_i + 3); + keyascii[keyascii_i++] = '+'; + keyascii[keyascii_i++] = '\n'; + keyascii[keyascii_i++] = 0; + return keyascii; +} + +void foleo_rsa_keygen(uint16_t bitWidth, rsakey_t* public, rsakey_t* private) +{ + if (bitWidth < 64) + { + fprintf(stderr, "foleo_rsa_keygen(): Do not use a bit-width smaller than 64.\n"); + exit(1); + } + + uint8_t* p = foleo_prigen(bitWidth / 16); + uint8_t* q = foleo_prigen(bitWidth / 16); + uint8_t* e = foleo_prigen(3); + mpz_init(public->n); + mpz_init(public->k); + mpz_init(private->n); + mpz_init(private->k); + + mpz_t np, nq; + mpz_init(np); + mpz_init(nq); + foleo_rsa_load(np, p, bitWidth / 16); + foleo_rsa_load(nq, q, bitWidth / 16); + foleo_rsa_load(public->k, e, 3); + public->bitWidth = bitWidth; + private->bitWidth = bitWidth; + mpz_mul(public->n, np, nq); + mpz_set(private->n, public->n); + mpz_sub_ui(np, np, 1); + mpz_sub_ui(nq, nq, 1); + mpz_mul(np, np, nq); + mpz_invert(private->k, public->k, np); + + mpz_clear(np); + mpz_clear(nq); + free(p); + free(q); + free(e); + + public->label = malloc(15); + public->label[ 0] = 'R'; + public->label[ 1] = 'S'; + public->label[ 2] = 'A'; + public->label[ 3] = ' '; + public->label[ 4] = 'P'; + public->label[ 5] = 'u'; + public->label[ 6] = 'b'; + public->label[ 7] = 'l'; + public->label[ 8] = 'i'; + public->label[ 9] = 'c'; + public->label[10] = ' '; + public->label[11] = 'K'; + public->label[12] = 'e'; + public->label[13] = 'y'; + public->label[14] = 0; + + private->label = malloc(16); + private->label[ 0] = 'R'; + private->label[ 1] = 'S'; + private->label[ 2] = 'A'; + private->label[ 3] = ' '; + private->label[ 4] = 'P'; + private->label[ 5] = 'r'; + private->label[ 6] = 'i'; + private->label[ 7] = 'v'; + private->label[ 8] = 'a'; + private->label[ 9] = 't'; + private->label[10] = 'e'; + private->label[11] = ' '; + private->label[12] = 'K'; + private->label[13] = 'e'; + private->label[14] = 'y'; + private->label[15] = 0; } void foleo_rsa_free(rsakey_t key) @@ -135,6 +468,7 @@ void foleo_rsa_free(rsakey_t key) key.bitWidth = -1; mpz_clear(key.n); mpz_clear(key.k); + if (key.label != NULL) free(key.label); } //convert to PKCS#1 v1.5 encryption block @@ -143,8 +477,9 @@ void foleo_rsa_free(rsakey_t key) static uint8_t* FOLEO_RSA_Pad(uint16_t size, uint8_t* buffer, uint16_t bufferSizeInBytes) { size /= 8; - if (bufferSizeInBytes - 11 > size) + if (bufferSizeInBytes > size - 11) { + fprintf(stderr, "foleo_rsa_encrypt(): Message size too large to pad!\n"); return NULL; } uint8_t* block = malloc(size); @@ -215,8 +550,9 @@ static uint8_t* FOLEO_RSA_DePad(uint16_t size, uint8_t* block, uint16_t* bufferS static uint8_t* FOLEO_RSA_PadSig(uint16_t size, uint8_t* buffer, uint16_t bufferSizeInBytes) { size /= 8; - if (bufferSizeInBytes - 11 > size) + if (bufferSizeInBytes > size - 11) { + fprintf(stderr, "foleo_rsa_encrypt(): Message size too large to pad!\n"); return NULL; } uint8_t* block = malloc(size); @@ -287,8 +623,9 @@ static uint8_t* FOLEO_RSA_PadOAEP(uint16_t size, uint8_t* buffer, uint16_t mLen) uint32_t mmLen = kLen - 2 * hLen - 2; //maximum message length uint32_t psLen = kLen - mLen - 2 * hLen - 2; //padding string length uint32_t dbLen = hLen + psLen + 1 + mLen; //datablock length - if (mLen > mmLen) + if (mLen > mmLen || mmLen > 1000) { + fprintf(stderr, "foleo_rsa_encrypt(): Message size too large to pad with OAEP!\n"); return NULL; } @@ -394,6 +731,11 @@ uint8_t* foleo_rsa_encrypt(rsakey_t key, uint8_t padding, uint8_t* buffer, uint1 } else { + if (bufferSize >= key.bitWidth / 8) + { + fprintf(stderr, "foleo_rsa_encrypt(): Message size too large for the modulus!\n"); + return NULL; + } eblock = FOLEO_RSA_Apply(key, buffer); } return eblock; @@ -421,4 +763,19 @@ uint8_t* foleo_rsa_decrypt(rsakey_t key, uint8_t padding, uint8_t* eblock, uint1 } return buffer; } + +//calculate the usable block size +uint16_t foleo_rsa_size(rsakey_t key, uint8_t padding) +{ + if (padding == FOLEO_RSA_ENCRYPTION || padding == FOLEO_RSA_SIGNATURE) + { + return (key.bitWidth / 8) - 11; + } + if (padding = FOLEO_RSA_OAEP) + { + return (key.bitWidth / 8) - 2 * 32 - 2; //sha-256 + } + return key.bitWidth / 8; +} + #endif diff --git a/tests/test.c b/tests/test.c index 753b811..25442f0 100644 --- a/tests/test.c +++ b/tests/test.c @@ -1,5 +1,6 @@ #include "../src/all.c" #include "cases.c" +#include void test_pbuf(char* p, uint8_t* b, uint32_t s) { @@ -15,7 +16,7 @@ void test_hmac(uint8_t grp, uint16_t id, uint8_t key[], uint16_t keyS, uint8_t d { uint8_t lbl1[] = " NIST"; uint8_t lbl2[] = "RCF#4231"; - uint8_t* out = foleo_hmac(foleo_sha256, 32, 64, key, keyS, data, dataS); + uint8_t* out = foleo_hmac(FOLEO_SHA256, key, keyS, data, dataS); for (uint16_t i = 0; i < resultS; i++) { if (out[i] != result[i]) @@ -31,7 +32,7 @@ void test_hmac(uint8_t grp, uint16_t id, uint8_t key[], uint16_t keyS, uint8_t d void test_hkdf(uint16_t id, uint8_t* ikm, uint32_t ikmS, uint8_t* salt, uint32_t saltS, uint8_t* info, uint32_t infoS, uint8_t* result, uint32_t resultS) { - uint8_t* out = foleo_hmac_hkdf(FOLEO_SHA256_PARAMETERS, resultS, ikm, ikmS, salt, saltS, info, infoS); + uint8_t* out = foleo_hmac_hkdf(FOLEO_SHA256, resultS, ikm, ikmS, salt, saltS, info, infoS); for (uint16_t i = 0; i < resultS; i++) { if (out[i] != result[i]) @@ -47,20 +48,51 @@ void test_hkdf(uint16_t id, uint8_t* ikm, uint32_t ikmS, uint8_t* salt, uint32_t void main() { - test_hmac(1, 1, NIST_HMAC_key1, sizeof(NIST_HMAC_key1), NIST_HMAC_data1, sizeof(NIST_HMAC_data1), NIST_HMAC_result1, sizeof(NIST_HMAC_result1)); - test_hmac(1, 2, NIST_HMAC_key2, sizeof(NIST_HMAC_key2), NIST_HMAC_data2, sizeof(NIST_HMAC_data2), NIST_HMAC_result2, sizeof(NIST_HMAC_result2)); - test_hmac(1, 3, NIST_HMAC_key3, sizeof(NIST_HMAC_key3), NIST_HMAC_data3, sizeof(NIST_HMAC_data3), NIST_HMAC_result3, sizeof(NIST_HMAC_result3)); - test_hmac(1, 4, NIST_HMAC_key4, sizeof(NIST_HMAC_key4), NIST_HMAC_data4, sizeof(NIST_HMAC_data4), NIST_HMAC_result4, sizeof(NIST_HMAC_result4)); - test_hmac(2, 1, RFC4231_HMAC_key1, sizeof(RFC4231_HMAC_key1), RFC4231_HMAC_data1, sizeof(RFC4231_HMAC_data1), RFC4231_HMAC_result1, sizeof(RFC4231_HMAC_result1)); - test_hmac(2, 2, RFC4231_HMAC_key2, sizeof(RFC4231_HMAC_key2), RFC4231_HMAC_data2, sizeof(RFC4231_HMAC_data2), RFC4231_HMAC_result2, sizeof(RFC4231_HMAC_result2)); - test_hmac(2, 3, RFC4231_HMAC_key3, sizeof(RFC4231_HMAC_key3), RFC4231_HMAC_data3, sizeof(RFC4231_HMAC_data3), RFC4231_HMAC_result3, sizeof(RFC4231_HMAC_result3)); - test_hmac(2, 4, RFC4231_HMAC_key4, sizeof(RFC4231_HMAC_key4), RFC4231_HMAC_data4, sizeof(RFC4231_HMAC_data4), RFC4231_HMAC_result4, sizeof(RFC4231_HMAC_result4)); - test_hmac(2, 5, RFC4231_HMAC_key5, sizeof(RFC4231_HMAC_key5), RFC4231_HMAC_data5, sizeof(RFC4231_HMAC_data5), RFC4231_HMAC_result5, sizeof(RFC4231_HMAC_result5)); - test_hmac(2, 6, RFC4231_HMAC_key6, sizeof(RFC4231_HMAC_key6), RFC4231_HMAC_data6, sizeof(RFC4231_HMAC_data6), RFC4231_HMAC_result6, sizeof(RFC4231_HMAC_result6)); - test_hmac(2, 7, RFC4231_HMAC_key7, sizeof(RFC4231_HMAC_key7), RFC4231_HMAC_data7, sizeof(RFC4231_HMAC_data7), RFC4231_HMAC_result7, sizeof(RFC4231_HMAC_result7)); + //test_hmac(1, 1, NIST_HMAC_key1, sizeof(NIST_HMAC_key1), NIST_HMAC_data1, sizeof(NIST_HMAC_data1), NIST_HMAC_result1, sizeof(NIST_HMAC_result1)); + //test_hmac(1, 2, NIST_HMAC_key2, sizeof(NIST_HMAC_key2), NIST_HMAC_data2, sizeof(NIST_HMAC_data2), NIST_HMAC_result2, sizeof(NIST_HMAC_result2)); + //test_hmac(1, 3, NIST_HMAC_key3, sizeof(NIST_HMAC_key3), NIST_HMAC_data3, sizeof(NIST_HMAC_data3), NIST_HMAC_result3, sizeof(NIST_HMAC_result3)); + //test_hmac(1, 4, NIST_HMAC_key4, sizeof(NIST_HMAC_key4), NIST_HMAC_data4, sizeof(NIST_HMAC_data4), NIST_HMAC_result4, sizeof(NIST_HMAC_result4)); + //test_hmac(2, 1, RFC4231_HMAC_key1, sizeof(RFC4231_HMAC_key1), RFC4231_HMAC_data1, sizeof(RFC4231_HMAC_data1), RFC4231_HMAC_result1, sizeof(RFC4231_HMAC_result1)); + //test_hmac(2, 2, RFC4231_HMAC_key2, sizeof(RFC4231_HMAC_key2), RFC4231_HMAC_data2, sizeof(RFC4231_HMAC_data2), RFC4231_HMAC_result2, sizeof(RFC4231_HMAC_result2)); + //test_hmac(2, 3, RFC4231_HMAC_key3, sizeof(RFC4231_HMAC_key3), RFC4231_HMAC_data3, sizeof(RFC4231_HMAC_data3), RFC4231_HMAC_result3, sizeof(RFC4231_HMAC_result3)); + //test_hmac(2, 4, RFC4231_HMAC_key4, sizeof(RFC4231_HMAC_key4), RFC4231_HMAC_data4, sizeof(RFC4231_HMAC_data4), RFC4231_HMAC_result4, sizeof(RFC4231_HMAC_result4)); + //test_hmac(2, 5, RFC4231_HMAC_key5, sizeof(RFC4231_HMAC_key5), RFC4231_HMAC_data5, sizeof(RFC4231_HMAC_data5), RFC4231_HMAC_result5, sizeof(RFC4231_HMAC_result5)); + //test_hmac(2, 6, RFC4231_HMAC_key6, sizeof(RFC4231_HMAC_key6), RFC4231_HMAC_data6, sizeof(RFC4231_HMAC_data6), RFC4231_HMAC_result6, sizeof(RFC4231_HMAC_result6)); + //test_hmac(2, 7, RFC4231_HMAC_key7, sizeof(RFC4231_HMAC_key7), RFC4231_HMAC_data7, sizeof(RFC4231_HMAC_data7), RFC4231_HMAC_result7, sizeof(RFC4231_HMAC_result7)); +// + //test_hkdf(1, RFC5869_HKDF_ikm1, sizeof(RFC5869_HKDF_ikm1), RFC5869_HKDF_salt1, sizeof(RFC5869_HKDF_salt1), RFC5869_HKDF_info1, sizeof(RFC5869_HKDF_info1), RFC5869_HKDF_result1, sizeof(RFC5869_HKDF_result1)); + //test_hkdf(2, RFC5869_HKDF_ikm2, sizeof(RFC5869_HKDF_ikm2), RFC5869_HKDF_salt2, sizeof(RFC5869_HKDF_salt2), RFC5869_HKDF_info2, sizeof(RFC5869_HKDF_info2), RFC5869_HKDF_result2, sizeof(RFC5869_HKDF_result2)); + //test_hkdf(3, RFC5869_HKDF_ikm3, sizeof(RFC5869_HKDF_ikm3), RFC5869_HKDF_salt3, sizeof(RFC5869_HKDF_salt3), RFC5869_HKDF_info3, sizeof(RFC5869_HKDF_info3), RFC5869_HKDF_result3, sizeof(RFC5869_HKDF_result3)); + + rsakey_t pub, prv; + foleo_rsa_keygen(2048, &pub, &prv); + + uint8_t* b1 = foleo_rsa_export(pub); + uint8_t* b2 = foleo_rsa_export(prv); + + foleo_rsa_free(pub); + foleo_rsa_free(prv); + pub = foleo_rsa_import(b1); + prv = foleo_rsa_import(b2); + + printf(">%i<\n", foleo_rsa_size(pub, FOLEO_RSA_ENCRYPTION)); + + uint8_t plaintext[245]; + for (uint16_t i = 0; i < sizeof(plaintext); i++) plaintext[i] = i; + uint8_t* ciphertext = foleo_rsa_encrypt(pub, FOLEO_RSA_ENCRYPTION, plaintext, sizeof(plaintext)); + uint16_t newSize; + uint8_t* newplaintext = foleo_rsa_decrypt(prv, FOLEO_RSA_ENCRYPTION, ciphertext, &newSize); + + test_pbuf("...", newplaintext, newSize); + + free(b1); + free(b2); + free(ciphertext); + free(newplaintext); + foleo_rsa_free(pub); + foleo_rsa_free(prv); + + - test_hkdf(1, RFC5869_HKDF_ikm1, sizeof(RFC5869_HKDF_ikm1), RFC5869_HKDF_salt1, sizeof(RFC5869_HKDF_salt1), RFC5869_HKDF_info1, sizeof(RFC5869_HKDF_info1), RFC5869_HKDF_result1, sizeof(RFC5869_HKDF_result1)); - test_hkdf(2, RFC5869_HKDF_ikm2, sizeof(RFC5869_HKDF_ikm2), RFC5869_HKDF_salt2, sizeof(RFC5869_HKDF_salt2), RFC5869_HKDF_info2, sizeof(RFC5869_HKDF_info2), RFC5869_HKDF_result2, sizeof(RFC5869_HKDF_result2)); - test_hkdf(3, RFC5869_HKDF_ikm3, sizeof(RFC5869_HKDF_ikm3), RFC5869_HKDF_salt3, sizeof(RFC5869_HKDF_salt3), RFC5869_HKDF_info3, sizeof(RFC5869_HKDF_info3), RFC5869_HKDF_result3, sizeof(RFC5869_HKDF_result3)); } -- 2.39.5