-
Notifications
You must be signed in to change notification settings - Fork 0
/
crypto-zsodium.adb
95 lines (79 loc) · 3.18 KB
/
crypto-zsodium.adb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package body Crypto.ZSodium is
function Generate_Shared_Key_curve25519xchacha20poly1305(
Recipient_PK: Public_Box_Key; Sender_SK: Secret_Box_Key)
return Box_Shared_Key is
use type Interfaces.C.int;
PK: aliased Interfaces.C.char_array :=
To_Chars(Recipient_PK);
PK_PTR: constant Interfaces.C.Strings.chars_ptr :=
Interfaces.C.Strings.To_Chars_Ptr(PK'Unchecked_Access);
SK: aliased Interfaces.C.char_array := To_Chars(Sender_SK);
SK_PTR: constant Interfaces.C.Strings.chars_ptr :=
Interfaces.C.Strings.To_Chars_Ptr(SK'Unchecked_Access);
SZ: constant Interfaces.C.size_t :=
Interfaces.C.size_t(cb_BEFORENMBYTES);
SH: aliased Interfaces.C.char_array := (1 .. SZ
=> Interfaces.C.nul);
SH_PTR: constant Interfaces.C.Strings.chars_ptr :=
Interfaces.C.Strings.To_Chars_Ptr(SH'Unchecked_Access);
Res: constant Interfaces.C.int :=
crypto_box_curve25519xchacha20poly1305_beforenm(
k => SH_PTR, pk => PK_PTR, sk => SK_PTR);
begin
if Res /= 0 then
raise Crypto_Error with
"crypto_box_..._beforenm failed, res = " &
Interfaces.C.int'Image(res);
end if;
return To_String(SH);
end Generate_Shared_Key_curve25519xchacha20poly1305;
function To_Chars(Buf: in String) return Interfaces.C.char_array is
use type Interfaces.C.size_t;
Ret: Interfaces.C.char_array(0 .. Buf'Length - 1);
for Ret'Address use Buf'Address;
begin
return Ret;
end To_Chars;
function To_String(Buf: in Interfaces.C.char_array) return String is
Ret: String(1 .. Buf'Length);
for Ret'Address use Buf'Address;
begin
return Ret;
end To_String;
function Decrypt_Message_curve25519xchacha20poly1305(
Ciphertext: in String; Shared_Key: in Box_Shared_Key;
Unique_Nonce: in Box_Nonce) return String is
use type Interfaces.C.size_t;
use type Interfaces.C.int;
CT: aliased Interfaces.C.char_array := To_Chars(Ciphertext);
CT_SZ: constant U64 := U64(CT'Length);
CT_PTR: constant Interfaces.C.Strings.chars_ptr :=
Interfaces.C.Strings.To_Chars_Ptr(CT'Unchecked_Access);
SH: aliased Interfaces.C.char_array := To_Chars(Shared_Key);
SH_PTR: constant Interfaces.C.Strings.chars_ptr :=
Interfaces.C.Strings.To_Chars_Ptr(SH'Unchecked_Access);
NC: aliased Interfaces.C.char_array :=
To_Chars(Unique_Nonce);
NC_PTR: constant Interfaces.C.Strings.chars_ptr :=
Interfaces.C.Strings.To_Chars_Ptr(NC'Unchecked_Access);
PT_SZ: constant Interfaces.C.size_t := Interfaces.C.size_t(
Plain_Text_Length(Ciphertext));
PT: aliased Interfaces.C.char_array := (1 .. PT_SZ
=> Interfaces.C.nul);
PT_PTR: constant Interfaces.C.Strings.chars_ptr :=
Interfaces.C.Strings.To_Chars_Ptr(PT'Unchecked_Access);
Res: constant Interfaces.C.int :=
crypto_box_curve25519xchacha20poly1305_open_easy_afternm
(m => PT_PTR, c => CT_PTR, clen => CT_SZ, n => NC_PTR,
k => SH_PTR);
begin
if Res /= 0 then
raise Crypto_Error with
"crypto_box_..._open_easy_afternm failed, " &
"res = " & Interfaces.C.int'Image(Res);
end if;
return To_String(PT);
end Decrypt_Message_curve25519xchacha20poly1305;
function Plain_Text_Length(CT: in String) return Positive is
(CT'Length - cb_MACBYTES);
end Crypto.ZSodium;