diff --git a/core/crypto/rand_bsd.odin b/core/crypto/rand_bsd.odin new file mode 100644 index 000000000..8e2be1d95 --- /dev/null +++ b/core/crypto/rand_bsd.odin @@ -0,0 +1,12 @@ +//+build freebsd, openbsd +package crypto + +foreign import libc "system:c" + +foreign libc { + arc4random_buf :: proc(buf: [^]byte, nbytes: uint) --- +} + +_rand_bytes :: proc(dst: []byte) { + arc4random_buf(raw_data(dst), len(dst)) +} diff --git a/core/crypto/rand_darwin.odin b/core/crypto/rand_darwin.odin new file mode 100644 index 000000000..ec44c1491 --- /dev/null +++ b/core/crypto/rand_darwin.odin @@ -0,0 +1,12 @@ +package crypto + +import "core:fmt" +import "core:sys/darwin" + +_rand_bytes :: proc(dst: []byte) { + res := darwin.SecRandomCopyBytes(count=len(dst), bytes=raw_data(dst)) + if res != .Success { + msg := darwin.CFStringCopyToOdinString(darwin.SecCopyErrorMessageString(res)) + panic(fmt.tprintf("crypto/rand_bytes: SecRandomCopyBytes returned non-zero result: %v %s", res, msg)) + } +} diff --git a/core/crypto/rand_generic.odin b/core/crypto/rand_generic.odin index fde91f85a..bf7abbbe2 100644 --- a/core/crypto/rand_generic.odin +++ b/core/crypto/rand_generic.odin @@ -1,7 +1,11 @@ +//+build !linux +//+build !windows +//+build !openbsd +//+build !freebsd +//+build !darwin +//+build !js package crypto -when ODIN_OS != .Linux && ODIN_OS != .OpenBSD && ODIN_OS != .Windows && ODIN_OS != .JS { - _rand_bytes :: proc(dst: []byte) { - unimplemented("crypto: rand_bytes not supported on this OS") - } +_rand_bytes :: proc(dst: []byte) { + unimplemented("crypto: rand_bytes not supported on this OS") } diff --git a/core/crypto/rand_openbsd.odin b/core/crypto/rand_openbsd.odin deleted file mode 100644 index bae97e8f0..000000000 --- a/core/crypto/rand_openbsd.odin +++ /dev/null @@ -1,12 +0,0 @@ -package crypto - -import "core:c" - -foreign import libc "system:c" -foreign libc { - arc4random_buf :: proc "c" (buf: rawptr, nbytes: c.size_t) --- -} - -_rand_bytes :: proc (dst: []byte) { - arc4random_buf(raw_data(dst), len(dst)) -} diff --git a/core/math/big/internal.odin b/core/math/big/internal.odin index 829cbf0e2..35c95f465 100644 --- a/core/math/big/internal.odin +++ b/core/math/big/internal.odin @@ -2046,9 +2046,9 @@ internal_int_inverse_modulo :: proc(dest, a, b: ^Int, allocator := context.alloc if internal_is_positive(a) && internal_eq(b, 1) { return internal_zero(dest) } /* - `b` cannot be negative and has to be > 1 + `b` cannot be negative and b has to be > 1 */ - if internal_is_negative(b) || internal_gt(b, 1) { return .Invalid_Argument } + if internal_is_negative(b) || !internal_gt(b, 1) { return .Invalid_Argument } /* If the modulus is odd we can use a faster routine instead. @@ -2954,4 +2954,4 @@ internal_zero_unused :: proc { internal_int_zero_unused, } /* ========================== End of low-level routines ========================== -*/ \ No newline at end of file +*/ diff --git a/core/sys/darwin/core_foundation.odin b/core/sys/darwin/core_foundation.odin new file mode 100644 index 000000000..eafe1a1f3 --- /dev/null +++ b/core/sys/darwin/core_foundation.odin @@ -0,0 +1,98 @@ +//+build darwin +package darwin + +import "core:runtime" + +foreign import core_foundation "system:CoreFoundation.framework" + +CFTypeRef :: distinct rawptr + +CFStringRef :: distinct CFTypeRef + +CFIndex :: int + +CFRange :: struct { + location: CFIndex, + length: CFIndex, +} + +CFStringEncoding :: enum u32 { + ASCII = 1, + NEXTSTEP = 2, + JapaneseEUC = 3, + UTF8 = 4, + ISOLatin1 = 5, + Symbol = 6, + NonLossyASCII = 7, + ShiftJIS = 8, + ISOLatin2 = 9, + Unicode = 10, + WindowsCP1251 = 11, + WindowsCP1252 = 12, + WindowsCP1253 = 13, + WindowsCP1254 = 14, + WindowsCP1250 = 15, + ISO2022JP = 21, + MacOSRoman = 30, + + UTF16 = Unicode, + + UTF16BigEndian = 0x90000100, + UTF16LittleEndian = 0x94000100, + + UTF32 = 0x8c000100, + UTF32BigEndian = 0x98000100, + UTF32LittleEndian = 0x9c000100, +} + +foreign core_foundation { + // Copies the character contents of a string to a local C string buffer after converting the characters to a given encoding. + CFStringGetCString :: proc(theString: CFStringRef, buffer: [^]byte, bufferSize: CFIndex, encoding: CFStringEncoding) -> Bool --- + + // Returns the number (in terms of UTF-16 code pairs) of Unicode characters in a string. + CFStringGetLength :: proc(theString: CFStringRef) -> CFIndex --- + + // Returns the maximum number of bytes a string of a specified length (in Unicode characters) will take up if encoded in a specified encoding. + CFStringGetMaximumSizeForEncoding :: proc(length: CFIndex, encoding: CFStringEncoding) -> CFIndex --- + + // Fetches a range of the characters from a string into a byte buffer after converting the characters to a specified encoding. + CFStringGetBytes :: proc( + thestring: CFStringRef, + range: CFRange, + encoding: CFStringEncoding, + lossByte: u8, + isExternalRepresentation: Bool, + buffer: [^]byte, + maxBufLen: CFIndex, + usedBufLen: ^CFIndex, + ) -> CFIndex --- + + // Releases a Core Foundation object. + @(link_name="CFRelease") + _CFRelease :: proc(cf: CFTypeRef) --- +} + +// Releases a Core Foundation object. +CFRelease :: proc { + CFReleaseString, +} + +// Releases a Core Foundation string. +CFReleaseString :: #force_inline proc(theString: CFStringRef) { + _CFRelease(CFTypeRef(theString)) +} + +CFStringCopyToOdinString :: proc(theString: CFStringRef, allocator := context.allocator) -> (str: string, ok: bool) #optional_ok { + length := CFStringGetLength(theString) + max := CFStringGetMaximumSizeForEncoding(length, .UTF8) + + buf, err := make([]byte, max, allocator) + if err != nil { return } + + raw_str := runtime.Raw_String{ + data = raw_data(buf), + } + CFStringGetBytes(theString, {0, length}, .UTF8, 0, false, raw_data(buf), max, &raw_str.len) + + return transmute(string)raw_str, true +} diff --git a/core/sys/darwin/darwin.odin b/core/sys/darwin/darwin.odin new file mode 100644 index 000000000..0b3efb1f5 --- /dev/null +++ b/core/sys/darwin/darwin.odin @@ -0,0 +1,4 @@ +//+build darwin +package darwin + +Bool :: b8 diff --git a/core/sys/darwin/security.odin b/core/sys/darwin/security.odin new file mode 100644 index 000000000..0c58260e7 --- /dev/null +++ b/core/sys/darwin/security.odin @@ -0,0 +1,26 @@ +//+build darwin +package darwin + +foreign import security "system:Security.framework" + +// A reference to a random number generator. +SecRandomRef :: distinct rawptr + +OSStatus :: distinct i32 + +errSec :: enum OSStatus { + Success = 0, // No error. + Unimplemented = -4, // Function or operation not implemented. + + // Many more... +} + +foreign security { + // Synonym for nil, uses a cryptographically secure random number generator. + kSecRandomDefault: SecRandomRef + + // Generates an array of cryptographically secure random bytes. + SecRandomCopyBytes :: proc(rnd: SecRandomRef = kSecRandomDefault, count: uint, bytes: [^]byte) -> errSec --- + + SecCopyErrorMessageString :: proc(status: errSec, reserved: rawptr = nil) -> CFStringRef --- +}