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*);
-void foleo_rsa_free(rsakey_t);
+void foleo_rsa_import(rsakey_t*, uint8_t*);
+uint8_t* foleo_rsa_export(rsakey_t*);
+void foleo_rsa_free(rsakey_t*);
+void foleo_rsa_keygen(uint16_t, rsakey_t*, rsakey_t*);
+uint16_t foleo_rsa_keysize();
+uint16_t foleo_rsa_size(rsakey_t, uint8_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);
-import System.IO
+import System.IO as IO
import Foreign
import Foreign.C.Types
+import Foreign.C.String
import Data.ByteString
import Data.ByteString.Internal
import Data.Word
import Data.ByteString.Unsafe
import Control.DeepSeq
+import qualified Data.ByteString.Internal as BI
+import qualified Foreign.Marshal.Utils as MU
+import qualified Data.ByteString.Char8 as C8
-foreign import ccall unsafe "prigen"
- c_prigen :: CUShort -> IO (Ptr CChar)
+foreign import ccall unsafe "foleo_rsa_keysize"
+ c_rsa_keysize :: IO(CUShort)
+foreign import ccall unsafe "foleo_rsa_keygen"
+ c_rsa_keygen :: CUShort -> Ptr() -> Ptr() -> IO()
-prigen :: Word16 -> IO ByteString
-prigen lengthInBytes = do
- ptr <- c_prigen (fromIntegral lengthInBytes)
- q <- unsafePackCStringLen (ptr, fromIntegral lengthInBytes)
- let out = copy q
- out `deepseq` free ptr
- return out
+foreign import ccall unsafe "foleo_rsa_export"
+ c_rsa_export :: Ptr () -> IO (Ptr CUChar)
+foreign import ccall unsafe "foleo_rsa_free"
+ c_rsa_free :: Ptr () -> IO ()
+foreign import ccall unsafe "free"
+ c_free :: Ptr a -> IO ()
+
+rsa_keygen :: Word16 -> (ByteString -> ByteString -> IO()) -> IO()
+rsa_keygen n fn = do
+ sRsaSize <- c_rsa_keysize
+ let rsaSize :: Int
+ rsaSize = fromIntegral sRsaSize
+ allocaBytes rsaSize $ \pubKeyPtr ->
+ allocaBytes rsaSize $ \prvKeyPtr -> do
+ c_rsa_keygen (fromIntegral n) pubKeyPtr prvKeyPtr
+ pubKey <- BI.create rsaSize (\ptr -> MU.copyBytes ptr (castPtr pubKeyPtr) rsaSize)
+ prvKey <- BI.create rsaSize (\ptr -> MU.copyBytes ptr (castPtr prvKeyPtr) rsaSize)
+ fn pubKey prvKey
+ rsa_free pubKey
+ rsa_free prvKey
+
+rsa_export :: ByteString -> IO(String)
+rsa_export blob = do
+ useAsCString blob $ \blobPtr -> do
+ cStrPtr <- c_rsa_export (castPtr blobPtr)
+ cStr <- peekCString (castPtr cStrPtr)
+ c_free cStrPtr
+ return cStr
+
+rsa_free :: ByteString -> IO()
+rsa_free blob = useAsCString blob $ \ptr -> c_rsa_free (castPtr ptr)
main :: IO()
main = do
- g <- prigen 256
- print $ byteStringToInteger g
+ rsa_keygen 2048 $ \pub prv -> do
+ spub <- rsa_export pub
+ IO.putStr spub
byteStringToInteger :: ByteString -> Integer
byteStringToInteger = foldl' (\acc byte -> acc * 256 + fromIntegral byte) 0
-
---```haskell
---import Data.ByteString (ByteString)
---import qualified Data.ByteString as BS
---
---byteStringToInteger :: ByteString -> Integer
---byteStringToInteger = BS.foldl' (\acc byte -> acc * 256 + fromIntegral byte) 0
---
\ No newline at end of file
--- /dev/null
+if [ "$1" == "test" ]
+then
+ gcc tests/test.c -o bin/test -lgmp -DDEVICE='"/dev/random"'
+ bin/test
+ rm bin/test
+else
+ gcc -shared -fPIC src/all.c -o bin/libCryptoFoleo.so -lgmp -DDEVICE='"/dev/random"'
+ cp src/headers.h bin/CryptoFoleo.h
+fi
if [ "$1" == "test" ]
then
gcc tests/test.c -o bin/test -lgmp -DDEVICE='"/dev/random"'
- bin/test
+ if [ "$2" == "hard" ]
+ then
+ valgrind bin/test
+ else
+ bin/test
+ fi
rm bin/test
else
gcc -shared -fPIC src/all.c -o bin/libCryptoFoleo.so -lgmp -DDEVICE='"/dev/random"'
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*);
-void foleo_rsa_free(rsakey_t);
+void foleo_rsa_import(rsakey_t*, uint8_t*);
+uint8_t* foleo_rsa_export(rsakey_t*);
+void foleo_rsa_free(rsakey_t*);
+void foleo_rsa_keygen(uint16_t, rsakey_t*, rsakey_t*);
+uint16_t foleo_rsa_keysize();
+uint16_t foleo_rsa_size(rsakey_t, uint8_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);
}
}
-//Keys and their sizes in terms of BYTES
-rsakey_t foleo_rsa_public(uint8_t* p, uint16_t pS, uint8_t* q, uint16_t qS, uint8_t* e, uint16_t eS)
-{
- mpz_t np, nq, ne;
- mpz_init(np);
- mpz_init(nq);
- mpz_init(ne);
- mpz_set_ui(np, 0);
- mpz_set_ui(nq, 0);
- mpz_set_ui(ne, 0);
-
- foleo_rsa_load(np, p, pS);
- foleo_rsa_load(nq, q, qS);
- foleo_rsa_load(ne, q, qS);
-
- rsakey_t ret;
- ret.bitWidth = (pS + qS) * 8;
- mpz_init(ret.n);
- mpz_init(ret.k);
- mpz_mul(ret.n, np, nq);
- mpz_set(ret.k, ne);
-
- mpz_clear(np);
- mpz_clear(nq);
- mpz_clear(ne);
- return ret;
-}
-
-rsakey_t foleo_rsa_private(uint8_t* p, uint16_t pS, uint8_t* q, uint16_t qS, uint8_t* e, uint16_t eS)
-{
- mpz_t np, nq, ne;
- mpz_init(np);
- mpz_init(nq);
- mpz_init(ne);
- mpz_set_ui(np, 0);
- mpz_set_ui(nq, 0);
- mpz_set_ui(ne, 0);
-
- foleo_rsa_load(np, p, pS);
- foleo_rsa_load(nq, q, qS);
- foleo_rsa_load(ne, q, qS);
-
- rsakey_t ret;
- ret.bitWidth = (pS + qS) * 8;
- mpz_init(ret.n);
- mpz_init(ret.k);
- mpz_mul(ret.n, np, nq);
- mpz_set(ret.k, ne);
-
- mpz_sub_ui(np, np, 1);
- mpz_sub_ui(nq, nq, 1);
- mpz_mul(np, np, nq);
- mpz_invert(ret.k, ret.k, np);
-
- mpz_clear(np);
- mpz_clear(nq);
- mpz_clear(ne);
- return ret;
-}
-
static uint8_t foleo_rsa_prettymap(uint8_t in, uint8_t dir)
{
if (dir)
}
}
-static rsakey_t foleo_rsa_import(uint8_t* buf)
+void foleo_rsa_import(rsakey_t* k, uint8_t* buf)
{
- 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);
+ 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;
if (buf[i] == ']')
{
state = 2;
- k.label = realloc(k.label, lblS + 1);
- k.label[lblS] = 0;
+ k->label = realloc(k->label, lblS + 1);
+ k->label[lblS] = 0;
}
else
{
- k.label = realloc(k.label, lblS + 1);
- k.label[lblS++] = buf[i];
+ 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));
+ mpz_mul_ui(k->k, k->k, 32);
+ mpz_add_ui(k->k, k->k, foleo_rsa_prettymap(buf[i], 1));
bitWidth += 1;
}
}
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));
+ 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 = 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++;
+ k->bitWidth = (k->bitWidth + 1) % 8 == 0 ? k->bitWidth + 1 : k->bitWidth - 1;
+ while (k->bitWidth % 8 != 0) k->bitWidth++;
}
- return k;
}
-static uint8_t* foleo_rsa_export(rsakey_t k)
+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);
+ mpz_set(n, k->n);
uint8_t* kn = malloc(0);
uint16_t knS = 0;
while (mpz_sgn(n) != 0)
kn[knS++] = foleo_rsa_prettymap(mpz_get_ui(t), 0);
mpz_div_ui(n, n, 32);
}
- mpz_set(n, k.k);
+ mpz_set(n, k->k);
uint8_t* kk = malloc(0);
uint16_t kkS = 0;
while (mpz_sgn(n) != 0)
uint32_t cnt = 0;
uint8_t nolabel = 0;
- if (k.label == NULL)
+ if (k->label == NULL)
{
nolabel = 1;
}
- else if (k.label[0] == 0)
+ else if (k->label[0] == 0)
{
nolabel = 1;
}
for (;;)
{
tmsg = realloc(tmsg, mS + 1);
- tmsg[mS++] = k.label[li++];
- if (k.label[li] == 0 || mS > (width / 3) * 2)
+ tmsg[mS++] = k->label[li++];
+ if (k->label[li] == 0 || mS > (width / 3) * 2)
{
tmsg = realloc(tmsg, mS + 2);
tmsg[mS++] = ']';
{
keyascii = realloc(keyascii, keyascii_i + 1);
keyascii[keyascii_i++] = ' ';
- mpz_set(n, k.n);
+ mpz_set(n, k->n);
cnt++;
if (cnt % width == 0)
{
private->label[13] = 'e';
private->label[14] = 'y';
private->label[15] = 0;
+
}
-void foleo_rsa_free(rsakey_t key)
+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);
+ 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
return key.bitWidth / 8;
}
+//returns the size of an rsa key
+uint16_t foleo_rsa_keysize()
+{
+ return sizeof(rsakey_t);
+}
+
#endif
//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));
+ //Randomly generate a private and public key
rsakey_t pub, prv;
- foleo_rsa_keygen(2048, &pub, &prv);
+ foleo_rsa_keygen(1024, &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);
+ uint8_t* tmp = foleo_rsa_export(&prv);
+ printf("%s\n", tmp);
+ ////Encrypt some plaintext into ciphertext
+ //uint8_t plaintext[] = "here is some plaintext to encrypt";
+ //uint8_t* ciphertext = foleo_rsa_encrypt(pub, FOLEO_RSA_OAEP, plaintext, sizeof(plaintext));
+ //
+ ////Display them
+ //test_pbuf("plaintext", plaintext, sizeof(plaintext));
+ //test_pbuf("ciphertext", ciphertext, 2048 / 8);
+ //
+ ////Decrypt the ciphertext
+ //uint16_t newSize;
+ //uint8_t* new_plaintext = foleo_rsa_decrypt(prv, FOLEO_RSA_OAEP, ciphertext, &newSize);
+//
+ ////Display it
+ //test_pbuf("new_plaintext", plaintext, newSize);
- free(b1);
- free(b2);
- free(ciphertext);
- free(newplaintext);
- foleo_rsa_free(pub);
- foleo_rsa_free(prv);
+ //free(ciphertext);
+ foleo_rsa_free(&pub);
+ foleo_rsa_free(&prv);