Skip to content

Commit

Permalink
Fix to/from array conversions for windows
Browse files Browse the repository at this point in the history
uint is **at least** 32 bit integer, according to the standard.
on windows, the uint has 64 bits, as in linux, but:
C.sizeof_ulong is 0x4 on windows.
ASAN does not like that.
but even if the value is stored, the code can't read it properly,
because bytesToUlong checks
`if sliceSize > C.sizeof_ulong`
  • Loading branch information
droppingin committed May 20, 2023
1 parent a81014c commit faeffac
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 19 deletions.
39 changes: 21 additions & 18 deletions common.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,35 +24,38 @@ package crypto11
import (
"C"
"encoding/asn1"
"encoding/binary"
"math"
"math/big"
"unsafe"

"github.com/miekg/pkcs11"
"github.com/pkg/errors"
)

func ulongToBytes(n uint) []byte {
return C.GoBytes(unsafe.Pointer(&n), C.sizeof_ulong) // ugh!
if n > math.MaxUint32 {
bytes := make([]byte, 8)
nn := uint64(n)
binary.LittleEndian.PutUint64(bytes, nn)
return bytes
}
bytes := make([]byte, 4)
nn := uint32(n)
binary.LittleEndian.PutUint32(bytes, nn)
return bytes
}

func bytesToUlong(bs []byte) (n uint) {
sliceSize := len(bs)
if sliceSize == 0 {
return 0
}

value := *(*uint)(unsafe.Pointer(&bs[0]))
if sliceSize > C.sizeof_ulong {
return value
}

// truncate the value to the # of bits present in the byte slice since
// the unsafe pointer will always grab/convert ULONG # of bytes
var mask uint
for i := 0; i < sliceSize; i++ {
mask |= 0xff << uint(i * 8)
const uint64Sz = 8
sz := len(bs)
if sz < uint64Sz {
placeholder := make([]byte, uint64Sz)
copy(placeholder, bs)
bs = placeholder
}
return value & mask
nn := binary.LittleEndian.Uint64(bs)
n = uint(nn)
return n
}

func concat(slices ...[]byte) []byte {
Expand Down
8 changes: 7 additions & 1 deletion common_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package crypto11

import (
"fmt"
"testing"
)

Expand All @@ -10,6 +11,11 @@ func TestULongMasking(t *testing.T) {

// Build an slice that is longer than the size of a ulong
extraLongSlice := append(ulongSlice, ulongSlice...)
expected := "AABBCCDD00112233AABBCCDD00112233"
actual := fmt.Sprintf("%X", string(extraLongSlice))
if expected != actual {
t.Errorf("expected %s != %s", expected, actual)
}

tests := []struct {
slice []uint8
Expand All @@ -30,7 +36,7 @@ func TestULongMasking(t *testing.T) {
for _, test := range tests {
got := bytesToUlong(test.slice)
if test.expected != got {
t.Errorf("conversion failed: 0x%X != 0x%X", test.expected, got)
t.Errorf("conversion failed: expected 0x%X != 0x%X", test.expected, got)
}
}
}

0 comments on commit faeffac

Please sign in to comment.