Skip to content

Commit 79e8200

Browse files
committed
Improve robustness of FIPS callback functions
This commit hardens several FIPS provider callback functions to make them safer and more robust against invalid inputs from the OpenSSL core. - Add null pointer checks in `fips_get_entropy` and `fips_get_nonce` to prevent crashes when the output buffer is null. - In `fips_get_nonce`, only mix in the salt if a valid salt pointer and length are provided. - Refactor `fips_bio_new_membuf` and `fips_bio_read_ex` for clarity and to use more idiomatic Rust patterns for handling buffer lengths and I/O results. Signed-off-by: Simo Sorce <[email protected]>
1 parent 0abf4a4 commit 79e8200

File tree

1 file changed

+38
-36
lines changed

1 file changed

+38
-36
lines changed

ossl/src/fips.rs

Lines changed: 38 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ unsafe extern "C" fn fips_get_entropy(
3232
min_len: usize,
3333
max_len: usize,
3434
) -> usize {
35+
if pout.is_null() {
36+
return 0;
37+
}
3538
let Ok(mut len) = usize::try_from(entropy) else {
3639
return 0;
3740
};
@@ -75,6 +78,9 @@ unsafe extern "C" fn fips_get_nonce(
7578
* we return just getrandom data | salt string.
7679
* Need to check if this is ok */
7780

81+
if pout.is_null() {
82+
return 0;
83+
}
7884
let Ok(entropy) = c_int::try_from(min_len) else {
7985
return 0;
8086
};
@@ -92,16 +98,18 @@ unsafe extern "C" fn fips_get_nonce(
9298
return 0;
9399
}
94100

95-
let mut len = out;
96-
if salt_len < len {
97-
len = salt_len;
98-
}
101+
if !salt.is_null() && salt_len > 0 {
102+
let mut len = out;
103+
if salt_len < len {
104+
len = salt_len;
105+
}
99106

100-
let r = unsafe { slice::from_raw_parts_mut(*pout as *mut u8, len) };
101-
let s = unsafe { slice::from_raw_parts(salt as *const u8, len) };
107+
let r = unsafe { slice::from_raw_parts_mut(*pout, len) };
108+
let s = unsafe { slice::from_raw_parts(salt as *const u8, len) };
102109

103-
for p in r.iter_mut().zip(s.iter()) {
104-
*p.0 |= *p.1;
110+
for p in r.iter_mut().zip(s.iter()) {
111+
*p.0 |= *p.1;
112+
}
105113
}
106114

107115
return out;
@@ -395,12 +403,12 @@ unsafe extern "C" fn fips_bio_new_membuf(
395403
buf: *const c_void,
396404
len: c_int,
397405
) -> *mut OSSL_CORE_BIO {
398-
let size = if len > 0 {
399-
usize::try_from(len).unwrap()
400-
} else if len < 0 {
401-
unsafe { libc::strlen(buf as *const c_char) }
402-
} else {
406+
if len == 0 {
403407
return null_mut();
408+
}
409+
let size = match usize::try_from(len) {
410+
Ok(s) => s,
411+
Err(_) => unsafe { libc::strlen(buf as *const c_char) },
404412
};
405413
let v = unsafe { slice::from_raw_parts_mut(buf as *mut u8, size) };
406414
Box::into_raw(Box::new(FipsBio {
@@ -414,37 +422,30 @@ unsafe extern "C" fn fips_bio_read_ex(
414422
data_len: usize,
415423
bytes_read: *mut usize,
416424
) -> c_int {
417-
let mut ret: std::os::raw::c_int = 0;
418425
if bio.is_null() {
419-
return ret;
426+
return 0;
420427
}
428+
421429
let mut readvec =
422430
unsafe { slice::from_raw_parts_mut(data as *mut u8, data_len) };
423431
let mut fbio: Box<FipsBio> = unsafe { Box::from_raw(bio as *mut FipsBio) };
424-
match fbio.op {
425-
Bio::FileOp(ref mut op) => match op.read(&mut readvec) {
426-
Ok(b) => {
427-
if b != 0 {
428-
ret = 1;
429-
unsafe { *bytes_read = b };
430-
}
431-
}
432-
Err(_) => ret = 0,
433-
},
434-
Bio::MemOp(ref mut op) => match op.read(&mut readvec) {
435-
Ok(b) => {
436-
if b != 0 {
437-
ret = 1;
438-
unsafe { *bytes_read = b };
439-
}
440-
}
441-
Err(_) => ret = 0,
442-
},
443-
}
432+
433+
let ret = match fbio.op {
434+
Bio::FileOp(ref mut op) => op.read(&mut readvec),
435+
Bio::MemOp(ref mut op) => op.read(&mut readvec),
436+
};
444437

445438
/* make sure we do not free the data yet */
446439
let _ = Box::leak(fbio);
447-
return ret;
440+
441+
if let Ok(b) = ret {
442+
if b != 0 {
443+
unsafe { *bytes_read = b };
444+
return 1;
445+
}
446+
}
447+
448+
0
448449
}
449450

450451
unsafe extern "C" fn fips_bio_free(bio: *mut OSSL_CORE_BIO) -> c_int {
@@ -455,6 +456,7 @@ unsafe extern "C" fn fips_bio_free(bio: *mut OSSL_CORE_BIO) -> c_int {
455456
}
456457
return 1;
457458
}
459+
458460
unsafe extern "C" fn fips_bio_vsnprintf(
459461
_buf: *mut c_char,
460462
_n: usize,

0 commit comments

Comments
 (0)