Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions aes.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,17 @@ package wolfSSL
// return -174;
// }
// #endif
// /* unlock/op/lock must stay inside one cgo call; see fips.go */
// static int wc_PBKDF2_Unlocked(byte* output, const byte* passwd, int pLen,
// const byte* salt, int sLen, int iterations,
// int kLen, int typeH)
// {
// int ret;
// PRIVATE_KEY_UNLOCK();
// ret = wc_PBKDF2(output, passwd, pLen, salt, sLen, iterations, kLen, typeH);
// PRIVATE_KEY_LOCK();
// return ret;
Comment thread
lealem47 marked this conversation as resolved.
// }
import "C"
import (
"unsafe"
Expand Down Expand Up @@ -274,10 +285,7 @@ func Wc_PBKDF2(out []byte, pwd []byte, pLen int, salt []byte, saltLen int, iter
if len(salt) > 0 {
saltPtr = (*C.uchar)(unsafe.Pointer(&salt[0]))
}
PRIVATE_KEY_UNLOCK()
ret := int(C.wc_PBKDF2(outPtr, pwdPtr, C.int(pLen),
return int(C.wc_PBKDF2_Unlocked(outPtr, pwdPtr, C.int(pLen),
saltPtr, C.int(saltLen), C.int(iter), C.int(kLen), C.int(typeH)))
PRIVATE_KEY_LOCK()
return ret
}

41 changes: 32 additions & 9 deletions ecc.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,35 @@ package wolfSSL
// (void)key; return -174;
// }
// #endif
// /* unlock/op/lock must stay inside one cgo call; see fips.go */
// static int wc_ecc_export_private_only_Unlocked(ecc_key* key, byte* out,
// word32* outLen)
// {
// int ret;
// PRIVATE_KEY_UNLOCK();
// ret = wc_ecc_export_private_only(key, out, outLen);
// PRIVATE_KEY_LOCK();
// return ret;
Comment thread
lealem47 marked this conversation as resolved.
// }
// static int wc_ecc_export_x963_ex_Unlocked(ecc_key* key, byte* out,
// word32* outLen, int compressed)
// {
// int ret;
// PRIVATE_KEY_UNLOCK();
// ret = wc_ecc_export_x963_ex(key, out, outLen, compressed);
// PRIVATE_KEY_LOCK();
// return ret;
// }
// static int wc_ecc_shared_secret_Unlocked(ecc_key* private_key,
// ecc_key* public_key,
// byte* out, word32* outLen)
// {
// int ret;
// PRIVATE_KEY_UNLOCK();
// ret = wc_ecc_shared_secret(private_key, public_key, out, outLen);
// PRIVATE_KEY_LOCK();
// return ret;
// }
import "C"
import (
"unsafe"
Expand Down Expand Up @@ -165,10 +194,8 @@ func Wc_ecc_export_private_only(key *C.struct_ecc_key, out []byte, outLen *int)
return BAD_FUNC_ARG
}
cOutLen := C.word32(*outLen)
PRIVATE_KEY_UNLOCK()
ret := int(C.wc_ecc_export_private_only(key, (*C.byte)(unsafe.Pointer(&out[0])), &cOutLen))
ret := int(C.wc_ecc_export_private_only_Unlocked(key, (*C.byte)(unsafe.Pointer(&out[0])), &cOutLen))
*outLen = int(cOutLen)
PRIVATE_KEY_LOCK()
return ret
}

Expand All @@ -177,10 +204,8 @@ func Wc_ecc_export_x963_ex(key *C.struct_ecc_key, out []byte, outLen *int, compr
return BAD_FUNC_ARG
}
cOutLen := C.word32(*outLen)
PRIVATE_KEY_UNLOCK()
ret := int(C.wc_ecc_export_x963_ex(key, (*C.byte)(unsafe.Pointer(&out[0])), &cOutLen, C.int(compressed)))
ret := int(C.wc_ecc_export_x963_ex_Unlocked(key, (*C.byte)(unsafe.Pointer(&out[0])), &cOutLen, C.int(compressed)))
*outLen = int(cOutLen)
PRIVATE_KEY_LOCK()
return ret
}

Expand Down Expand Up @@ -254,10 +279,8 @@ func Wc_ecc_shared_secret(privKey, pubKey *C.struct_ecc_key, out []byte, outLen
return BAD_FUNC_ARG
}
cOutLen := C.word32(*outLen)
PRIVATE_KEY_UNLOCK()
ret := int(C.wc_ecc_shared_secret(privKey, pubKey, (*C.uchar)(unsafe.Pointer(&out[0])), &cOutLen))
ret := int(C.wc_ecc_shared_secret_Unlocked(privKey, pubKey, (*C.uchar)(unsafe.Pointer(&out[0])), &cOutLen))
*outLen = int(cOutLen)
PRIVATE_KEY_LOCK()
return ret
}

Expand Down
23 changes: 22 additions & 1 deletion fips.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ package wolfSSL
// return -174;
// }
// #endif
// #define WC_SPKRE_F(x,y) wolfCrypt_SetPrivateKeyReadEnable_fips((x),(y))
Comment thread
sebastian-carpenter marked this conversation as resolved.
// #ifdef HAVE_FIPS
// int WC_PRIVATE_KEY_LOCK(void) {
// return WC_SPKRE_F(0,WC_KEYTYPE_ALL);
Expand Down Expand Up @@ -76,10 +75,32 @@ func Wc_SetDefaultSeed_Cb() int {
return int(C.wc_SetSeed_Cb((C.wc_RngSeed_Cb)(C.wc_GenerateSeed)))
}

// FIPS private-key gate.
//
// wolfCrypt's FIPS APIs refuse to read private-key material unless the
// calling thread has enabled it. In userspace builds that enable flag is
// per-OS-thread instead of process-wide.
//
// A goroutine is pinned to its OS thread only for the duration of a single
// cgo call. Calling PRIVATE_KEY_UNLOCK, then the wolfCrypt operation, then
// PRIVATE_KEY_LOCK as three separate cgo calls therefore leaves a window in
// which the scheduler can move the goroutine to another thread. The
// operation then runs on a thread whose counter was never incremented and
// fails with FIPS_PRIVATE_KEY_LOCKED_E (-287), while the thread that took
// the unlock is left permanently unlocked.
//
// The Wc_* wrappers in this go-wolfssl avoid that by performing unlock,
// operation and lock inside one static C helper (wc_HKDF_Unlocked,
// wc_PBKDF2_Unlocked, ...).
//
// PRIVATE_KEY_LOCK and PRIVATE_KEY_UNLOCK are exported but they act on the
// calling OS thread's counter, so any direct callers must hold
// runtime.LockOSThread() across the entire unlock/operation/lock sequence.
func PRIVATE_KEY_LOCK() int {
return int(C.WC_PRIVATE_KEY_LOCK())
}

// See PRIVATE_KEY_LOCK for the threading requirements.
func PRIVATE_KEY_UNLOCK() int {
return int(C.WC_PRIVATE_KEY_UNLOCK())
}
Expand Down
17 changes: 13 additions & 4 deletions hmac.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,18 @@ package wolfSSL
// free(ptr);
// }
// #endif
// /* unlock/op/lock must stay inside one cgo call; see fips.go */
// static int wc_HKDF_Unlocked(int type, const byte* inKey, word32 inKeySz,
// const byte* salt, word32 saltSz,
// const byte* info, word32 infoSz,
// byte* out, word32 outSz)
// {
// int ret;
// PRIVATE_KEY_UNLOCK();
// ret = wc_HKDF(type, inKey, inKeySz, salt, saltSz, info, infoSz, out, outSz);
// PRIVATE_KEY_LOCK();
// return ret;
Comment thread
lealem47 marked this conversation as resolved.
// }
import "C"
import (
"unsafe"
Expand Down Expand Up @@ -119,12 +131,9 @@ func Wc_HKDF(hashType int, inputKey []byte, inputKeySz int, salt []byte,
if len(info) > 0 {
infoPtr = (*C.uchar)(unsafe.Pointer(&info[0]))
}
PRIVATE_KEY_UNLOCK()
ret := int(C.wc_HKDF(C.int(hashType), ikmPtr,
return int(C.wc_HKDF_Unlocked(C.int(hashType), ikmPtr,
C.word32(inputKeySz), saltPtr,
C.word32(saltSz), infoPtr,
C.word32(infoSz), (*C.uchar)(unsafe.Pointer(&out[0])),
C.word32(outSz)))
PRIVATE_KEY_LOCK()
return ret
}
Loading