secure-enclave-unlocker #24

Merged
sneak merged 7 commits from secure-enclave-unlocker into main 2026-03-14 07:36:28 +01:00
Showing only changes of commit e10b4cec82 - Show all commits

View File

@@ -1,5 +1,4 @@
//go:build darwin //go:build darwin
// +build darwin
// Package macse provides Go bindings for macOS Secure Enclave operations // Package macse provides Go bindings for macOS Secure Enclave operations
// using CryptoTokenKit identities created via sc_auth. // using CryptoTokenKit identities created via sc_auth.
@@ -41,16 +40,14 @@ const (
// CreateKey creates a new P-256 non-exportable key in the Secure Enclave via sc_auth. // CreateKey creates a new P-256 non-exportable key in the Secure Enclave via sc_auth.
// Returns the uncompressed public key bytes (65 bytes) and the identity hash (for deletion). // Returns the uncompressed public key bytes (65 bytes) and the identity hash (for deletion).
func CreateKey(label string) (publicKey []byte, hash string, err error) { func CreateKey(label string) (publicKey []byte, hash string, err error) {
cLabel := C.CString(label)
defer C.free(unsafe.Pointer(cLabel))
pubKeyBuf := make([]C.uint8_t, p256UncompressedKeySize) pubKeyBuf := make([]C.uint8_t, p256UncompressedKeySize)
pubKeyLen := C.int(p256UncompressedKeySize) pubKeyLen := C.int(p256UncompressedKeySize)
var hashBuf [hashBufferSize]C.char var hashBuf [hashBufferSize]C.char
var errBuf [errorBufferSize]C.char var errBuf [errorBufferSize]C.char
cLabel := C.CString(label)
defer C.free(unsafe.Pointer(cLabel)) //nolint:nlreturn // CGo free pattern
result := C.se_create_key(cLabel, result := C.se_create_key(cLabel,
&pubKeyBuf[0], &pubKeyLen, &pubKeyBuf[0], &pubKeyLen,
&hashBuf[0], C.int(hashBufferSize), &hashBuf[0], C.int(hashBufferSize),
@@ -60,7 +57,7 @@ func CreateKey(label string) (publicKey []byte, hash string, err error) {
return nil, "", fmt.Errorf("secure enclave: %s", C.GoString(&errBuf[0])) return nil, "", fmt.Errorf("secure enclave: %s", C.GoString(&errBuf[0]))
} }
pk := C.GoBytes(unsafe.Pointer(&pubKeyBuf[0]), pubKeyLen) pk := C.GoBytes(unsafe.Pointer(&pubKeyBuf[0]), pubKeyLen) //nolint:nlreturn // CGo result extraction
h := C.GoString(&hashBuf[0]) h := C.GoString(&hashBuf[0])
return pk, h, nil return pk, h, nil
@@ -70,15 +67,13 @@ func CreateKey(label string) (publicKey []byte, hash string, err error) {
// (eciesEncryptionStandardVariableIVX963SHA256AESGCM). // (eciesEncryptionStandardVariableIVX963SHA256AESGCM).
// Encryption uses only the public key; no SE interaction required. // Encryption uses only the public key; no SE interaction required.
func Encrypt(label string, plaintext []byte) ([]byte, error) { func Encrypt(label string, plaintext []byte) ([]byte, error) {
cLabel := C.CString(label)
defer C.free(unsafe.Pointer(cLabel))
ciphertextBuf := make([]C.uint8_t, maxCiphertextSize) ciphertextBuf := make([]C.uint8_t, maxCiphertextSize)
ciphertextLen := C.int(maxCiphertextSize) ciphertextLen := C.int(maxCiphertextSize)
var errBuf [errorBufferSize]C.char var errBuf [errorBufferSize]C.char
cLabel := C.CString(label)
defer C.free(unsafe.Pointer(cLabel)) //nolint:nlreturn // CGo free pattern
result := C.se_encrypt(cLabel, result := C.se_encrypt(cLabel,
(*C.uint8_t)(unsafe.Pointer(&plaintext[0])), C.int(len(plaintext)), (*C.uint8_t)(unsafe.Pointer(&plaintext[0])), C.int(len(plaintext)),
&ciphertextBuf[0], &ciphertextLen, &ciphertextBuf[0], &ciphertextLen,
@@ -88,21 +83,21 @@ func Encrypt(label string, plaintext []byte) ([]byte, error) {
return nil, fmt.Errorf("secure enclave: %s", C.GoString(&errBuf[0])) return nil, fmt.Errorf("secure enclave: %s", C.GoString(&errBuf[0]))
} }
return C.GoBytes(unsafe.Pointer(&ciphertextBuf[0]), ciphertextLen), nil out := C.GoBytes(unsafe.Pointer(&ciphertextBuf[0]), ciphertextLen) //nolint:nlreturn // CGo result extraction
return out, nil
} }
// Decrypt decrypts ECIES ciphertext using the SE-backed private key. // Decrypt decrypts ECIES ciphertext using the SE-backed private key.
// The ECDH portion of decryption is performed inside the Secure Enclave. // The ECDH portion of decryption is performed inside the Secure Enclave.
func Decrypt(label string, ciphertext []byte) ([]byte, error) { func Decrypt(label string, ciphertext []byte) ([]byte, error) {
cLabel := C.CString(label)
defer C.free(unsafe.Pointer(cLabel))
plaintextBuf := make([]C.uint8_t, maxPlaintextSize) plaintextBuf := make([]C.uint8_t, maxPlaintextSize)
plaintextLen := C.int(maxPlaintextSize) plaintextLen := C.int(maxPlaintextSize)
var errBuf [errorBufferSize]C.char var errBuf [errorBufferSize]C.char
cLabel := C.CString(label)
defer C.free(unsafe.Pointer(cLabel)) //nolint:nlreturn // CGo free pattern
result := C.se_decrypt(cLabel, result := C.se_decrypt(cLabel,
(*C.uint8_t)(unsafe.Pointer(&ciphertext[0])), C.int(len(ciphertext)), (*C.uint8_t)(unsafe.Pointer(&ciphertext[0])), C.int(len(ciphertext)),
&plaintextBuf[0], &plaintextLen, &plaintextBuf[0], &plaintextLen,
@@ -112,17 +107,18 @@ func Decrypt(label string, ciphertext []byte) ([]byte, error) {
return nil, fmt.Errorf("secure enclave: %s", C.GoString(&errBuf[0])) return nil, fmt.Errorf("secure enclave: %s", C.GoString(&errBuf[0]))
} }
return C.GoBytes(unsafe.Pointer(&plaintextBuf[0]), plaintextLen), nil out := C.GoBytes(unsafe.Pointer(&plaintextBuf[0]), plaintextLen) //nolint:nlreturn // CGo result extraction
return out, nil
} }
// DeleteKey removes a CTK identity from the Secure Enclave via sc_auth. // DeleteKey removes a CTK identity from the Secure Enclave via sc_auth.
func DeleteKey(hash string) error { func DeleteKey(hash string) error {
cHash := C.CString(hash)
defer C.free(unsafe.Pointer(cHash))
var errBuf [errorBufferSize]C.char var errBuf [errorBufferSize]C.char
cHash := C.CString(hash)
defer C.free(unsafe.Pointer(cHash)) //nolint:nlreturn // CGo free pattern
result := C.se_delete_key(cHash, &errBuf[0], C.int(errorBufferSize)) result := C.se_delete_key(cHash, &errBuf[0], C.int(errorBufferSize))
if result != 0 { if result != 0 {