Skip to content
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

Introduce elykseer crypto library #16

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[submodule "ext/prngsharp.git"]
path = ext/prngsharp.git
url = https://github.com/CodiePP/prngsharp.git
[submodule "ext/openssl-net.git"]
path = ext/openssl-net.git
url = https://github.com/CodiePP/openssl-net.git
[submodule "ext/elykseer-crypto.git"]
path = ext/elykseer-crypto.git
url = https://github.com/eLyKseeR/elykseer-crypto.git
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ script:
- nuget restore -PackagesDirectory packages packages.config
- nuget restore -PackagesDirectory packages UT/packages.config
- git submodule update --remote
- cd ext/openssl-net.git/; ./build.Linux.jenkins.sh
- cd ext/elykseer-crypto; ./build.Linux.jenkins.sh
- cd ../..
- cd ext/prngsharp.git/; ./build.Linux.jenkins.sh
- cd ../..
Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,8 @@ and build it.
extract source code in the parent directory: ext/prngsharp.git
and build it. Also, run `mk_Linux.sh` to create the native library. For other
platforms call the appropriate script.

## Testing specific unit test

> ``mono ./packages/NUnit.ConsoleRunner.3.10.0/tools/nunit3-console.exe --test=TestAes UT/bin/Debug/UT.exe``

6 changes: 6 additions & 0 deletions UT/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

run single test
===============

mono ../packages/NUnit.ConsoleRunner.3.10.0/tools/nunit3-console.exe bin/Debug/UT.exe --test=TestAes

30 changes: 19 additions & 11 deletions UT/UT.OSX.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,19 @@
<Reference Include="Unquote">
<HintPath>../packages/Unquote.4.0.0/lib/net45/Unquote.dll</HintPath>
</Reference>
<Reference Include="ManagedOpenSsl">
<HintPath>../ext/openssl-net.git/bin/Debug/ManagedOpenSsl.dll</HintPath>
</Reference>
<Reference Include="sharpPRNG">
<HintPath>../ext/prngsharp.git/sharpPRNG/sharpPRNG/bin/Debug/sharpPRNG.dll</HintPath>
</Reference>
<Reference Include="System.Xml" />
<Reference Include="nunit.framework">
<HintPath>..\packages\NUnit.3.12.0\lib\net45\nunit.framework.dll</HintPath>
</Reference>
<Reference Include="FSharp.Core">
<HintPath>..\packages\FSharp.Core.4.6.2\lib\net45\FSharp.Core.dll</HintPath>
</Reference>
<Reference Include="sharpPRNG">
<HintPath>..\ext\prngsharp\sharpPRNG\sharpPRNG\bin\Debug\sharpPRNG.dll</HintPath>
</Reference>
<Reference Include="elykseer-crypto-cs">
<HintPath>..\ext\elykseer-crypto\src\csharp\elykseer-crypto-cs.dll</HintPath>
</Reference>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath32)/../Microsoft SDKs/F#/4.0/Framework/v4.0/Microsoft.FSharp.Targets" />
<ItemGroup>
Expand Down Expand Up @@ -76,18 +76,26 @@
<Compile Include="tests/TestLogging.fs">
<Link>TestLogging.fs</Link>
</Compile>
<None Include="../../sharpPRNG_development/libprngCpp.osx.1.0.5.dylib">
<Link>libprngCpp.osx.1.0.5.dylib</Link>
<None Include="packages.config" />
<None Include="..\ext\elykseer-crypto\src\csharp\elykseer-crypto-cs.dll">
<Link>elykseer-crypto-cs.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="..\ext\elykseer-crypto\src\csharp\elykseer-crypto-cs.dll.config">
<Link>elykseer-crypto-cs.dll.config</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="../../sharpPRNG_development/sharpPRNG/sharpPRNG/bin/Debug/sharpPRNG.dll.config">
<Link>sharpPRNG.dll.config</Link>
<None Include="..\ext\elykseer-crypto\src\csharp\libelykseer-crypto-cs.osx.1.0.1.dylib">
<Link>libelykseer-crypto-cs.osx.1.0.1.dylib</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="..\ext\elykseer-crypto\BUILD\src\libelykseer-crypto_Debug.1.0.7.dylib">
<Link>libelykseer-crypto_Debug.1.0.7.dylib</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<ProjectReference Include="../base/eLyKseeR-base.OSX.fsproj">
<Project>{F0AE1EB0-9463-45A4-9E38-8D8033A0B850}</Project>
<Name>eLyKseeR-base.OSX</Name>
</ProjectReference>
<None Include="packages.config" />
</ItemGroup>
</Project>
58 changes: 35 additions & 23 deletions UT/tests/TestAes.fs
Original file line number Diff line number Diff line change
Expand Up @@ -19,52 +19,64 @@

module TestAes

open System
open NUnit.Framework
open eLyKseeR

[<Test>]
let ``can encrypt and decrypt``() =
let k = Key256.create ()
let smsg = "this is a message to be en/decrypted and compared"
let msg = Array.create 256 (byte 0)
for i = 0 to (String.length smsg - 1) do
msg.[i] <- byte smsg.[i]
let msg = Array.create (String.length smsg) (byte 0)
String.iteri (fun i c -> msg.[i] <- byte(c)) smsg

printf "\noriginal plaintext: \n"
Array.iter (fun b -> printf "%02x " b) msg
printf "\n"

let msg2 = Aes.encrypt k msg
printf "\nencrypted: \n"
Array.iter (fun b -> printf "%02x " b) msg2
printf "\n"

let msg3 = Aes.decrypt k msg2
printf "\ndecrypted: \n"
Array.iter (fun b -> printf "%02x " b) msg3
printf "\n"
Assert.AreEqual(msg, msg3)
Assert.AreEqual(smsg, msg3.[0 .. String.length smsg - 1])

let msg4 = Aes.encrypt k msg3
let msg5 = Aes.decrypt k msg4
Assert.AreEqual(msg, msg5)

[<Test>]
let ``huge buffer: encrypt and decrypt``() =
let k = Key256.create ()
//let smsg = "0123456789"
let smsg = Key256.create() |> Key256.toHex
let sz = 16*Chunk.width*Chunk.height
let smsg = "0123456789"
let sz = 16*Chunk.width*Chunk.height // 4 MB
let msg = Array.create sz (byte 0)
let mutable idx = 0
while idx < sz do
for i = 0 to (String.length smsg - 1) do
if (idx+i) < sz then
msg.[idx+i] <- byte smsg.[i]
idx <- idx + 10

printfn "\noriginal plaintext: "
//Array.iter (fun b -> printf "%02x " b) msg
let mutable tenc = Array.create 100 (int 0)
let mutable tdec = Array.create 100 (int 0)

let msg2 = Aes.encrypt k msg
Assert.LessOrEqual(msg.Length, msg2.Length)
Assert.AreEqual(16, msg2.Length - msg.Length)
printfn "\nencrypted: %d" msg2.Length
//Array.iter (fun b -> printf "%02x " b) msg2
for i in 1 .. 100 do
let t0 = DateTime.Now
let msg2 = Aes.encrypt k msg
Assert.AreEqual(msg.Length, msg2.Length)

let msg3 = Aes.decrypt k msg2
Assert.AreEqual(msg.Length, msg3.Length)
printfn "\ndecrypted: %d" msg3.Length
//Array.iter (fun b -> printf "%02x " b) msg3
let t1 = DateTime.Now
let msg3 = Aes.decrypt k msg2
let t2 = DateTime.Now
tenc.[i-1] <- (t1 - t0).Milliseconds
tdec.[i-1] <- (t2 - t1).Milliseconds

Assert.AreEqual(msg.Length, msg3.Length)
Assert.AreEqual(msg, msg3)

//System.Console.WriteLine("time for encryption: {0} ms", (t1 - t0).Milliseconds)
//System.Console.WriteLine("time for decryption: {0} ms", (t2 - t1).Milliseconds)
System.Array.Sort(tenc)
System.Array.Sort(tdec)
System.Console.WriteLine("time for encryption: {0} < {1} < {2}", tenc.[0], tenc.[50], tenc.[99])
System.Console.WriteLine("time for decryption: {0} < {1} < {2}", tdec.[0], tdec.[50], tdec.[99])
27 changes: 7 additions & 20 deletions base/eLyKseeR-base.OSX.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,18 @@
<Reference Include="System.Core" />
<Reference Include="System.Numerics" />
<Reference Include="System.Security" />
<Reference Include="ManagedOpenSsl">
<HintPath>../ext/openssl-net.git/bin/Debug/ManagedOpenSsl.dll</HintPath>
</Reference>
<Reference Include="System.Xml" />
<Reference Include="Mono.Posix" />
<Reference Include="sharpPRNG">
<HintPath>../ext/prngsharp.git/sharpPRNG/sharpPRNG/bin/Debug/sharpPRNG.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="FSharp.Core">
<HintPath>packages\FSharp.Core.4.6.2\lib\net45\FSharp.Core.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="sharpPRNG">
<HintPath>..\ext\prngsharp\sharpPRNG\sharpPRNG\bin\Debug\sharpPRNG.dll</HintPath>
</Reference>
<Reference Include="elykseer-crypto-cs">
<HintPath>..\ext\elykseer-crypto\src\csharp\elykseer-crypto-cs.dll</HintPath>
</Reference>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath32)/../Microsoft SDKs/F#/4.0/Framework/v4.0/Microsoft.FSharp.Targets" />
<ItemGroup />
Expand Down Expand Up @@ -182,19 +181,7 @@
<Compile Include="src/BackupCtrl.fs">
<Link>BackupCtrl.fs</Link>
</Compile>
<None Include="../ext/openssl-net.git/bin/Debug/ManagedOpenSsl.dll.config">
<Link>ManagedOpenSsl.dll.config</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="../ext/openssl-net.git/bin/Debug/libcrypto.osx.1.0.2.dylib">
<Link>libcrypto.osx.1.0.2.dylib</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="../ext/openssl-net.git/bin/Debug/libssl.osx.1.0.2.dylib">
<Link>libssl.osx.1.0.2.dylib</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="../ext/prngsharp.git/sharpPRNG/sharpPRNG/bin/Debug/sharpPRNG.dll.config">
<None Include="../ext/prngsharp/sharpPRNG/sharpPRNG/bin/Debug/sharpPRNG.dll.config">
<Link>sharpPRNG.dll.config</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
Expand Down
94 changes: 69 additions & 25 deletions base/src/Aes.fs
Original file line number Diff line number Diff line change
Expand Up @@ -21,33 +21,77 @@ namespace eLyKseeR

module Aes =

open OpenSSL.Crypto

exception BadLength
exception ProcError of string

let aes_crypt b l key n d =
let kbytes = Key256.bytes key
let abytes = Key256.bytes <| AppId.salt
// salt is 8 bytes
let salt = Array.create 8 (byte 0)
for i = 0 to 7 do
salt.[i] <- abytes.[31-i]
// iv is 128 bits (16 bytes)
let iv = Array.create 16 (byte 0)

let cc = new CipherContext(Cipher.AES_256_CBC)
let key = cc.BytesToKey(MessageDigest.SHA256, salt, kbytes, 1, ref iv)
if d then
cc.Encrypt(b, key, iv)
let blockenc p (maxsz : uint32) (inbuf : byte[]) : byte[] =
let len = uint32(Array.length inbuf)
if len = uint32 0
then Array.empty
else
cc.Decrypt(b, key, iv)
let outbuf = Array.create (int(len)) (byte 0)
let mutable tempb = Array.create (int(maxsz)) (byte 0)
let mutable outlen = uint32 0
let mutable count = uint32 0
while count < len do
let sz = min maxsz (len - count)
let c = int(count)
//System.Console.WriteLine(Printf.sprintf "sz = %i count = %i" sz c)
System.Buffer.BlockCopy(inbuf, c, tempb, 0, int(sz))
let nproc = lxr.Aes.proc_AesEncrypt(p, uint32(sz), &tempb)
count <- count + uint32(nproc)
let available = lxr.Aes.len_AesEncrypt(p)
let copied = lxr.Aes.copy_AesEncrypt(p, maxsz, &tempb)
System.Buffer.BlockCopy(tempb, 0, outbuf, int(outlen), int(copied))
outlen <- outlen + copied
//System.Console.WriteLine(Printf.sprintf "nproc = %i avail = %i copied = %i tempb[0]='%02x' tempb[1]='%02x'"
//nproc available copied tempb.[0] tempb.[1])

let fin = lxr.Aes.fin_AesEncrypt(p)
if (fin > 0)
then
let copied = lxr.Aes.copy_AesEncrypt(p, maxsz, &tempb)
System.Buffer.BlockCopy(tempb, 0, outbuf, int(outlen), int(copied))
else ()
outbuf

let blockdec p (maxsz : uint32) (inbuf : byte[]) : byte[] =
let len = uint32(Array.length inbuf)
let outbuf = Array.create (int(len)) (byte 0)
let mutable tempb = Array.create (int(maxsz)) (byte 0)
let mutable outlen = uint32 0
let mutable count = uint32 0
while count < len do
let sz = min maxsz (len - count)
let c = int(count)
let b = inbuf.[c .. c + int(sz) - 1]
let nproc = lxr.Aes.proc_AesDecrypt(p, uint32(sz), ref b)
count <- count + uint32(nproc)
let available = lxr.Aes.len_AesDecrypt(p)
let copied = lxr.Aes.copy_AesDecrypt(p, maxsz, &tempb)
System.Buffer.BlockCopy(tempb, 0, outbuf, int(outlen), int(copied))
outlen <- outlen + copied

let fin = lxr.Aes.fin_AesDecrypt(p)
if (fin > 0)
then
let copied = lxr.Aes.copy_AesDecrypt(p, maxsz, &tempb)
System.Buffer.BlockCopy(tempb, 0, outbuf, int(outlen), int(copied))
else ()
outbuf

let encrypt (k : Key256.t) (b : byte array) =
let l = Array.length b in
if l % 16 <> 0 then raise BadLength
else aes_crypt b l k 256 true
let encrypt (key : Key256.t) (buf : byte array) : byte array =
let iv = lxr.Key128.fromhex_Key128(AppId.salt)
let aesEnc = lxr.Aes.mk_AesEncrypt(Key256.ctype key, iv)
let encrypted = blockenc aesEnc (lxr.Aes.sz_AesEncrypt()) buf
lxr.Key128.release_Key128(iv)
lxr.Aes.release_AesEncrypt(aesEnc)
encrypted

let decrypt (k : Key256.t) (b : byte array) =
let l = Array.length b in
if l % 16 <> 0 then raise BadLength
else aes_crypt b l k 256 false
let decrypt (key : Key256.t) (buf : byte array) : byte array =
let iv = lxr.Key128.fromhex_Key128(AppId.salt)
let aesDec = lxr.Aes.mk_AesDecrypt(Key256.ctype key, iv)
let decrypted = blockdec aesDec (lxr.Aes.sz_AesDecrypt()) buf
lxr.Key128.release_Key128(iv)
lxr.Aes.release_AesDecrypt(aesDec)
decrypted
2 changes: 1 addition & 1 deletion base/src/AppId.fs
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ module internal AppId =
(** the salt is to select individual encryption with AES
attention! data encrypted with one salt cannot be decrypted with another
*)
let salt = Key256.fromHex "a7261fc15f4e515c024810aef0350c2a295e13057b81695f87fa03778ec57e1d"
let salt = "a7261fc15f4e515c024810aef0350c2a295e13057b81695f87fa03778ec57e1d"
2 changes: 1 addition & 1 deletion base/src/AppId.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ module internal AppId =

val appid : string

val salt : Key256.t
val salt : string //Key256.t
22 changes: 16 additions & 6 deletions base/src/Key128.fs
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,31 @@ namespace eLyKseeR

module Key128 =

type CKey128 = lxr.SWIGTYPE_p_CKey128

type t = {
key128 : byte array;
//key128 : byte array;
key128 : CKey128 // internal
}

//[<Literal>]
let length = 128

let nbytes = length / 8

let ctype k = k.key128

let create () =
let k = Key.create nbytes in
{ key128 = k }
{ key128 = lxr.Key128.mk_Key128() }
//let k = Key.create nbytes in
//{ key128 = k }

let toHex k = Key.toHex nbytes k.key128
let toHex k = lxr.Key128.tohex_Key128(k.key128)
//Key.toHex nbytes k.key128

let fromHex s = { key128 = Key.fromHex nbytes s }
let fromHex s =
{ key128 = lxr.Key128.fromhex_Key128(s) }
//{ key128 = Key.fromHex nbytes s }

let bytes k = k.key128
let bytes k = lxr.Key128.tohex_Key128(k.key128) |>
Key.fromHex nbytes
4 changes: 4 additions & 0 deletions base/src/Key128.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ module Key128 =

type t

type CKey128 = lxr.SWIGTYPE_p_CKey128

val ctype : t -> CKey128

val length : int
(** length of the key in bytes *)

Expand Down
Loading