/
ChachaPoly.xs
107 lines (92 loc) · 2.16 KB
/
ChachaPoly.xs
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
96
97
98
99
100
101
102
103
104
105
106
107
#define PERL_NO_GET_CONTEXT
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
#include "src/chacha.c"
#include "src/poly1305.c"
typedef struct chacha_ctx *Crypt__OpenSSH__ChachaPoly;
MODULE = Crypt::OpenSSH::ChachaPoly PACKAGE = Crypt::OpenSSH::ChachaPoly
PROTOTYPES: ENABLE
Crypt::OpenSSH::ChachaPoly
new(class,key)
SV *class
SV *key
CODE:
{
STRLEN keysize;
keysize = SvCUR(key);
if (keysize != 16 && keysize != 32)
croak ("The key must be 128 or 256 bits long");
Newxz(RETVAL, 1, struct chacha_ctx);
chacha_keysetup(RETVAL, (unsigned char *) SvPV_nolen(key), keysize*8);
}
OUTPUT:
RETVAL
SV *
encrypt(self,data)
Crypt::OpenSSH::ChachaPoly self
SV *data
ALIAS:
decrypt = 1
CODE:
{
STRLEN size;
void *bytes = SvPV(data,size);
if (size) {
RETVAL = NEWSV (0, size);
SvPOK_only (RETVAL);
SvCUR_set (RETVAL, size);
chacha_encrypt_bytes(self, bytes, (unsigned char *) SvPV_nolen(RETVAL), (int) size);
} else {
RETVAL = newSVpv ("", 0);
}
}
OUTPUT:
RETVAL
void
ivsetup(self,iv,counter)
Crypt::OpenSSH::ChachaPoly self
SV *iv
SV *counter
CODE:
{
STRLEN iv_l ; unsigned char *iv_p = (unsigned char *) SvPVbyte (iv, iv_l);
/* anything beyond 64 bits is ignored */
if (iv_l < 8) {
croak("ivsetup: iv must be 64 bits long!");
}
STRLEN counter_l ; unsigned char *counter_p = (unsigned char *) SvPVbyte (counter, counter_l);
if (counter_l == 0)
counter_p = NULL;
/* anything beyond 8 chars is ignored */
else if (counter_l < 8)
croak ("ivsetup: counter must be 64 bits long!");
chacha_ivsetup(self, iv_p, counter_p);
}
void
DESTROY(self)
Crypt::OpenSSH::ChachaPoly self
CODE:
Safefree(self);
SV *
poly1305(self,data,key)
Crypt::OpenSSH::ChachaPoly self
SV *data
SV *key
CODE:
{
STRLEN size;
void *databytes = SvPV(data,size);
STRLEN keysize;
keysize = SvCUR(key);
if (keysize != POLY1305_KEYLEN)
croak("Key is incorrect size");
void *keybytes = SvPV_nolen(key);
RETVAL = NEWSV(0, POLY1305_TAGLEN);
SvPOK_only (RETVAL);
SvCUR_set (RETVAL, POLY1305_TAGLEN);
poly1305_auth((unsigned char *) SvPV_nolen(RETVAL),databytes,(int) size,keybytes);
}
OUTPUT:
RETVAL