Skip to content

Commit 56d8d46

Browse files
authored
Allocate ssl/crypto output buffers one way (#111)
`ssl/crypto` allocated output buffers two ways: `@pony_alloc` plus `from_cpointer` in the eight hash primitives and `Digest.final`, and `Array[U8].init` in `RandBytes`, `HmacSha256` and `Pbkdf2Sha256`. The two are equivalent to the garbage collector, as #77 established. This uses `Array.init` everywhere: the higher-level API, with no raw pointer to hand to `from_cpointer`. The hash FFI declarations took `md: Pointer[U8]` to match `@pony_alloc`'s return. They take `Pointer[U8] tag` now, which is what `cpointer()` gives and what `RandBytes` and the others already use for an output buffer. With no production caller left, `@pony_alloc` is gone; `@pony_ctx` moves to `_test.pony`, next to the other test-only FFI declarations. Closes #108
1 parent eef9294 commit 56d8d46

4 files changed

Lines changed: 37 additions & 43 deletions

File tree

ssl/crypto/_test.pony

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use "pony_test"
22
use "pony_check"
33

44
use @memset[Pointer[None]](dst: Pointer[None], value: I32, n: USize)
5+
use @pony_ctx[Pointer[None]]()
56
use @pony_triggergc[None](ctx: Pointer[None])
67

78
actor \nodoc\ Main is TestList

ssl/crypto/crypto.pony

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,3 @@ The one-shot hash functions and `ConstantTimeCompare` cannot fail and are total.
2525
When `HmacSha256` raises, reject the message. Do not compare it against a code
2626
of your own making — a code you invent is one an attacker can send you.
2727
"""
28-
29-
use @pony_ctx[Pointer[None]]()
30-
use @pony_alloc[Pointer[U8]](ctx: Pointer[None], size: USize)

ssl/crypto/digest.pony

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -203,10 +203,7 @@ class Digest
203203
if _ctx.is_null() then error end
204204

205205
let size = _digest_size
206-
let digest =
207-
recover String.from_cpointer(
208-
@pony_alloc(@pony_ctx(), size), size)
209-
end
206+
let digest = recover Array[U8].init(0, size) end
210207

211208
var rc: I32 = 0
212209
ifdef "openssl_3.0.x" or "openssl_4.0.x" then
@@ -231,12 +228,11 @@ class Digest
231228
end
232229
_ctx = Pointer[_EVPCTX]
233230

234-
// `@pony_alloc` does not zero the memory it returns, so a digest OpenSSL
235-
// did not write holds whatever this actor freed last. Raising drops it
236-
// rather than handing it back as a hash.
231+
// On failure OpenSSL wrote nothing, so `digest` is still all zeros.
232+
// Raise rather than hand a buffer OpenSSL did not fill back as a hash.
237233
if rc != 1 then error end
238234

239-
let h = (consume digest).array()
235+
let h: Array[U8] val = consume digest
240236
_hash = h
241237
h
242238
end

ssl/crypto/hash_fn.pony

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ use "path:/usr/local/opt/libressl/lib" if osx and x86
22
use "path:/opt/homebrew/opt/libressl/lib" if osx and arm
33
use "lib:crypto"
44

5-
use @MD4[Pointer[U8]](d: Pointer[U8] tag, n: USize, md: Pointer[U8])
6-
use @MD5[Pointer[U8]](d: Pointer[U8] tag, n: USize, md: Pointer[U8])
7-
use @RIPEMD160[Pointer[U8]](d: Pointer[U8] tag, n: USize, md: Pointer[U8])
8-
use @SHA1[Pointer[U8]](d: Pointer[U8] tag, n: USize, md: Pointer[U8])
9-
use @SHA224[Pointer[U8]](d: Pointer[U8] tag, n: USize, md: Pointer[U8])
10-
use @SHA256[Pointer[U8]](d: Pointer[U8] tag, n: USize, md: Pointer[U8])
11-
use @SHA384[Pointer[U8]](d: Pointer[U8] tag, n: USize, md: Pointer[U8])
12-
use @SHA512[Pointer[U8]](d: Pointer[U8] tag, n: USize, md: Pointer[U8])
5+
use @MD4[Pointer[U8]](d: Pointer[U8] tag, n: USize, md: Pointer[U8] tag)
6+
use @MD5[Pointer[U8]](d: Pointer[U8] tag, n: USize, md: Pointer[U8] tag)
7+
use @RIPEMD160[Pointer[U8]](d: Pointer[U8] tag, n: USize, md: Pointer[U8] tag)
8+
use @SHA1[Pointer[U8]](d: Pointer[U8] tag, n: USize, md: Pointer[U8] tag)
9+
use @SHA224[Pointer[U8]](d: Pointer[U8] tag, n: USize, md: Pointer[U8] tag)
10+
use @SHA256[Pointer[U8]](d: Pointer[U8] tag, n: USize, md: Pointer[U8] tag)
11+
use @SHA384[Pointer[U8]](d: Pointer[U8] tag, n: USize, md: Pointer[U8] tag)
12+
use @SHA512[Pointer[U8]](d: Pointer[U8] tag, n: USize, md: Pointer[U8] tag)
1313

1414
use "format"
1515

@@ -30,9 +30,9 @@ primitive MD4 is HashFn
3030
fun apply(input: ByteSeq): Array[U8] val =>
3131
recover
3232
let size: USize = 16
33-
let digest = @pony_alloc(@pony_ctx(), size)
34-
@MD4(input.cpointer(), input.size(), digest)
35-
Array[U8].from_cpointer(digest, size)
33+
let arr = Array[U8].init(0, size)
34+
@MD4(input.cpointer(), input.size(), arr.cpointer())
35+
arr
3636
end
3737

3838
primitive MD5 is HashFn
@@ -42,9 +42,9 @@ primitive MD5 is HashFn
4242
fun apply(input: ByteSeq): Array[U8] val =>
4343
recover
4444
let size: USize = 16
45-
let digest = @pony_alloc(@pony_ctx(), size)
46-
@MD5(input.cpointer(), input.size(), digest)
47-
Array[U8].from_cpointer(digest, size)
45+
let arr = Array[U8].init(0, size)
46+
@MD5(input.cpointer(), input.size(), arr.cpointer())
47+
arr
4848
end
4949

5050
primitive RIPEMD160 is HashFn
@@ -55,9 +55,9 @@ primitive RIPEMD160 is HashFn
5555
fun apply(input: ByteSeq): Array[U8] val =>
5656
recover
5757
let size: USize = 20
58-
let digest = @pony_alloc(@pony_ctx(), size)
59-
@RIPEMD160(input.cpointer(), input.size(), digest)
60-
Array[U8].from_cpointer(digest, size)
58+
let arr = Array[U8].init(0, size)
59+
@RIPEMD160(input.cpointer(), input.size(), arr.cpointer())
60+
arr
6161
end
6262

6363
primitive SHA1 is HashFn
@@ -68,9 +68,9 @@ primitive SHA1 is HashFn
6868
fun apply(input: ByteSeq): Array[U8] val =>
6969
recover
7070
let size: USize = 20
71-
let digest = @pony_alloc(@pony_ctx(), size)
72-
@SHA1(input.cpointer(), input.size(), digest)
73-
Array[U8].from_cpointer(digest, size)
71+
let arr = Array[U8].init(0, size)
72+
@SHA1(input.cpointer(), input.size(), arr.cpointer())
73+
arr
7474
end
7575

7676
primitive SHA224 is HashFn
@@ -81,9 +81,9 @@ primitive SHA224 is HashFn
8181
fun apply(input: ByteSeq): Array[U8] val =>
8282
recover
8383
let size: USize = 28
84-
let digest = @pony_alloc(@pony_ctx(), size)
85-
@SHA224(input.cpointer(), input.size(), digest)
86-
Array[U8].from_cpointer(digest, size)
84+
let arr = Array[U8].init(0, size)
85+
@SHA224(input.cpointer(), input.size(), arr.cpointer())
86+
arr
8787
end
8888

8989
primitive SHA256 is HashFn
@@ -94,9 +94,9 @@ primitive SHA256 is HashFn
9494
fun apply(input: ByteSeq): Array[U8] val =>
9595
recover
9696
let size: USize = 32
97-
let digest = @pony_alloc(@pony_ctx(), size)
98-
@SHA256(input.cpointer(), input.size(), digest)
99-
Array[U8].from_cpointer(digest, size)
97+
let arr = Array[U8].init(0, size)
98+
@SHA256(input.cpointer(), input.size(), arr.cpointer())
99+
arr
100100
end
101101

102102
primitive SHA384 is HashFn
@@ -107,9 +107,9 @@ primitive SHA384 is HashFn
107107
fun apply(input: ByteSeq): Array[U8] val =>
108108
recover
109109
let size: USize = 48
110-
let digest = @pony_alloc(@pony_ctx(), size)
111-
@SHA384(input.cpointer(), input.size(), digest)
112-
Array[U8].from_cpointer(digest, size)
110+
let arr = Array[U8].init(0, size)
111+
@SHA384(input.cpointer(), input.size(), arr.cpointer())
112+
arr
113113
end
114114

115115
primitive SHA512 is HashFn
@@ -120,9 +120,9 @@ primitive SHA512 is HashFn
120120
fun apply(input: ByteSeq): Array[U8] val =>
121121
recover
122122
let size: USize = 64
123-
let digest = @pony_alloc(@pony_ctx(), size)
124-
@SHA512(input.cpointer(), input.size(), digest)
125-
Array[U8].from_cpointer(digest, size)
123+
let arr = Array[U8].init(0, size)
124+
@SHA512(input.cpointer(), input.size(), arr.cpointer())
125+
arr
126126
end
127127

128128
primitive ToHexString

0 commit comments

Comments
 (0)