diff --git a/Cargo.toml b/Cargo.toml index 9720658..d137dc5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,7 @@ categories = ["api-bindings", "cryptography", "hardware-support"] keywords = ["ccid", "ecdsa", "rsa", "piv", "yubikey"] [dependencies] +getrandom = "0.1" libc = "0.2" log = "0.4" zeroize = "1" diff --git a/src/internal.rs b/src/internal.rs index 689bb07..4a80894 100644 --- a/src/internal.rs +++ b/src/internal.rs @@ -69,7 +69,6 @@ extern "C" { keylen: i32, out: *mut u8, ) -> i32; - fn RAND_bytes(buf: *mut u8, num: i32) -> i32; } /// DES-related errors @@ -234,26 +233,6 @@ pub unsafe fn yk_des_is_weak_key(key: *const u8, _cb_key: usize) -> bool { DES_is_weak_key(key as (*mut [u8; 8])) != 0 } -/// PRNG errors/results -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -#[repr(i32)] -pub enum PRngErrorKind { - /// Ok - Ok = 0, - - /// General error - GeneralError = -1, -} - -/// Generate bytes with the PRNG -pub unsafe fn _ykpiv_prng_generate(buffer: *mut u8, cb_req: usize) -> PRngErrorKind { - if RAND_bytes(buffer, cb_req as (i32)) != -1 { - PRngErrorKind::Ok - } else { - PRngErrorKind::GeneralError - } -} - /// PKCS#5 error types #[derive(Clone, Copy, Debug, Eq, PartialEq)] #[repr(i32)] diff --git a/src/util.rs b/src/util.rs index d8842ee..68442d5 100644 --- a/src/util.rs +++ b/src/util.rs @@ -34,8 +34,10 @@ #![allow(clippy::missing_safety_doc, clippy::too_many_arguments)] use crate::{consts::*, error::ErrorKind, internal::*, yubikey::*}; +use getrandom::getrandom; use libc::{calloc, free, memcpy, memmove, realloc, time}; use log::{error, warn}; +use std::ops::DerefMut; use std::{ffi::CString, mem, os::raw::c_void, ptr}; use zeroize::{Zeroize, Zeroizing}; @@ -125,9 +127,7 @@ pub unsafe fn ykpiv_util_set_cardid( let mut res = Ok(()); if cardid.is_null() { - if _ykpiv_prng_generate(id.as_mut_ptr(), id.len()) != PRngErrorKind::Ok { - return Err(ErrorKind::RandomnessError); - } + getrandom(&mut id).map_err(|_| ErrorKind::RandomnessError)?; } else { memcpy( id.as_mut_ptr() as (*mut c_void), @@ -215,9 +215,7 @@ pub unsafe fn ykpiv_util_set_cccid( let len: usize; if ccc.is_null() { - if _ykpiv_prng_generate(id.as_mut_ptr(), id.len()) != PRngErrorKind::Ok { - return Err(ErrorKind::RandomnessError); - } + getrandom(&mut id).map_err(|_| ErrorKind::RandomnessError)?; } else { memcpy( id.as_mut_ptr() as (*mut c_void), @@ -1593,7 +1591,6 @@ pub unsafe fn ykpiv_util_set_protected_mgm( state: &mut YubiKey, mgm: *mut YkPivMgm, ) -> Result<(), ErrorKind> { - let mut prngrc: PRngErrorKind; let mut f_generate: bool; let mut mgm_key = Zeroizing::new([0u8; 24]); // TODO(tarcieri): replace vec with wrapper type that impls `Zeroize` @@ -1632,9 +1629,8 @@ pub unsafe fn ykpiv_util_set_protected_mgm( loop { if f_generate { // generate a new mgm key - prngrc = _ykpiv_prng_generate(mgm_key.as_mut_ptr(), mgm_key.len()); - if prngrc != PRngErrorKind::Ok { - error!("could not generate new mgm, err = {:?}", prngrc); + if let Err(e) = getrandom(mgm_key.deref_mut()) { + error!("could not generate new mgm, err = {}", e); let _ = _ykpiv_end_transaction(state); return Err(ErrorKind::RandomnessError); } diff --git a/src/yubikey.rs b/src/yubikey.rs index a130dcf..18c9a8e 100644 --- a/src/yubikey.rs +++ b/src/yubikey.rs @@ -39,9 +39,10 @@ use crate::{ error::ErrorKind, internal::{ des_decrypt, des_destroy_key, des_encrypt, des_import_key, yk_des_is_weak_key, - DesErrorKind, DesKey, PRngErrorKind, _ykpiv_prng_generate, + DesErrorKind, DesKey, }, }; +use getrandom::getrandom; use libc::{c_char, free, malloc, memcmp, memcpy, memmove, memset, strlen, strncasecmp}; use log::{error, info, trace, warn}; use std::{convert::TryInto, ffi::CStr, mem, os::raw::c_void, ptr, slice}; @@ -851,26 +852,18 @@ pub unsafe fn ykpiv_authenticate(state: &mut YubiKey, mut key: *const u8) -> Res apdu.data[1] = 20; // 2 + 8 + 2 +8 apdu.data[2] = 0x80; apdu.data[3] = 8; - memcpy( - apdu.data[4..12].as_mut_ptr() as *mut c_void, - response.as_ptr() as *const c_void, - 8, - ); + apdu.data[4..12].copy_from_slice(&response); apdu.data[12] = 0x81; apdu.data[13] = 8; - if _ykpiv_prng_generate(data[14..20].as_mut_ptr(), 8) == PRngErrorKind::GeneralError { + if getrandom(&mut data[14..22]).is_err() { error!("failed getting randomness for authentication."); let _ = _ykpiv_end_transaction(state); return Err(ErrorKind::RandomnessError); } + challenge.copy_from_slice(&data[14..22]); - memcpy( - challenge.as_mut_ptr() as *mut c_void, - data[14..20].as_ptr() as *const c_void, - 8, - ); - apdu.lc = 20; + apdu.lc = 22; res = _send_data(state, &mut apdu, data.as_mut_ptr(), &mut recv_len, &mut sw);