diff --git a/.github/workflows/kryoptic-fips.yml b/.github/workflows/kryoptic-fips.yml new file mode 100644 index 00000000..a9eac293 --- /dev/null +++ b/.github/workflows/kryoptic-fips.yml @@ -0,0 +1,137 @@ +--- +name: Test kryoptic FIPS module + +on: [push, pull_request, workflow_dispatch] + +jobs: + build: + name: Test kryoptic FIPS module + runs-on: ubuntu-22.04 + container: quay.io/fedora/fedora:latest + steps: + ################# + ### DNF cache ### + ################# + - name: Get Date for DNF cache entry + id: get-date + run: | + echo "date=$(/bin/date -u "+%Y%V")" >> $GITHUB_OUTPUT + shell: bash + + - name: Restore DNF cache + uses: actions/cache/restore@v4 + id: cache-dnf + with: + path: "/var/cache/libdnf5" + key: fedora-dnf-${{ steps.get-date.outputs.date }} + + - name: Install Dependencies + run: | + dnf -y install git cargo clang-devel openssl-devel sqlite-devel \ + 'perl(FindBin)' 'perl(lib)' 'perl(File::Compare)' \ + 'perl(File::Copy)' 'perl(bigint)' 'perl(Time::HiRes)' \ + 'perl(IPC::Cmd)' 'perl(Pod::Html)' 'perl(Digest::SHA)' \ + 'perl(Module::Load::Conditional)' 'perl(File::Temp)' \ + 'perl(Test::Harness)' 'perl(Test::More)' 'perl(Math::BigInt)' \ + 'perl(Time::Piece)' zlib-devel sed sqlite-devel + + - name: DNF cache + if: ${{ steps.cache-dnf.outputs.cache-hit != 'true' }} + uses: actions/cache/save@v4 + with: + path: "/var/cache/libdnf5" + key: fedora-dnf-${{ steps.get-date.outputs.date }} + + ##################### + ### OpenSSL build ### + ##################### + - name: Setup OpenSSL 3.5 + id: ossl-setup + run: | + OPENSSL_BRANCH="openssl-3.5" + + cd .. + git clone https://github.com/openssl/openssl.git \ + --single-branch --branch $OPENSSL_BRANCH openssl + cd openssl + echo "KRYOPTIC_OPENSSL_SOURCES=$PWD" >> "$GITHUB_ENV" + echo "cacheid=${{ runner.os }}-ossl-$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT" + + - name: Restore OpenSSL build if cached + uses: actions/cache/restore@v4 + id: cache + with: + path: ${{ env.KRYOPTIC_OPENSSL_SOURCES }} + key: ${{ steps.ossl-setup.outputs.cacheid }} + + - name: Build OpenSSL + if: ${{ steps.cache.outputs.cache-hit != 'true' }} + run: | + pushd ${{ env.KRYOPTIC_OPENSSL_SOURCES }} + ./Configure + make + + - name: Cache OpenSSL 3.5 build + if: ${{ steps.cache.outputs.cache-hit != 'true' }} + uses: actions/cache/save@v4 + with: + path: ${{ env.KRYOPTIC_OPENSSL_SOURCES }} + key: ${{ steps.ossl-setup.outputs.cacheid }} + + ###################### + ### kryoptic build ### + ###################### + - name: Setup kryoptic + run: | + KRYOPTIC_REVISION="v1.3.1" + + cd .. + git clone https://github.com/latchset/kryoptic.git \ + --depth 1 --single-branch --revision $KRYOPTIC_REVISION kryoptic + + - name: Generate lock file + run: | + cd ../kryoptic && + cargo generate-lockfile + + - name: Cache Rust dependencies + uses: actions/cache@v4 + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + ../kryoptic/target/ + key: fedora-cargo-${{ hashFiles('**/Cargo.lock') }} + + - name: Build kryoptic + run: | + FEATURES="fips,pqc,dummy-integrity" + OPTS="--no-default-features" + + cd ../kryoptic && + cargo build -vv $OPTS --features "$FEATURES" + + - uses: actions/upload-artifact@v4 + if: failure() + with: + name: Build logs OpenSSL version 3.5 + path: | + target/debug/build/*/output + + - name: Checkout rust-cryptoki + uses: actions/checkout@v4 + + ################# + ### the tests ### + ################# + - name: Run test script + env: + KRYOPTIC_CONF: /tmp/kryoptic.sql + TEST_PKCS11_MODULE: /__w/rust-cryptoki/kryoptic/target/debug/libkryoptic_pkcs11.so + OUT_DIR: /__w/rust-cryptoki/kryoptic/target/debug/deps/ + run: | + RUST_BACKTRACE=1 cargo build --all-features && + RUST_BACKTRACE=1 cargo test + diff --git a/cryptoki-sys/build.rs b/cryptoki-sys/build.rs index 582a4b31..c1dec796 100644 --- a/cryptoki-sys/build.rs +++ b/cryptoki-sys/build.rs @@ -31,6 +31,7 @@ mod generate { ("CKC_", "CK_CERTIFICATE_TYPE"), ("CKD_", "CK_EC_KDF_TYPE"), ("CKF_", "CK_FLAGS"), + ("CKV_", "CK_ULONG"), ("CKG_MGF1_", "CK_RSA_PKCS_MGF_TYPE"), ("CKG", "CK_GENERATOR_FUNCTION"), ("CKH_", "CK_HW_FEATURE_TYPE"), diff --git a/cryptoki-sys/src/bindings/aarch64-apple-darwin.rs b/cryptoki-sys/src/bindings/aarch64-apple-darwin.rs index dc7c75e2..dad0c585 100644 --- a/cryptoki-sys/src/bindings/aarch64-apple-darwin.rs +++ b/cryptoki-sys/src/bindings/aarch64-apple-darwin.rs @@ -1039,14 +1039,14 @@ pub const CKT_TRUST_MUST_VERIFY_TRUST: u32 = 4; pub const CKU_SO: CK_USER_TYPE = 0; pub const CKU_USER: CK_USER_TYPE = 1; pub const CKU_CONTEXT_SPECIFIC: CK_USER_TYPE = 2; -pub const CKV_AUTHORITY_TYPE_UNSPECIFIED: u32 = 0; -pub const CKV_AUTHORITY_TYPE_NIST_CMVP: u32 = 1; -pub const CKV_AUTHORITY_TYPE_COMMON_CRITERIA: u32 = 2; -pub const CKV_TYPE_UNSPECIFIED: u32 = 0; -pub const CKV_TYPE_SOFTWARE: u32 = 1; -pub const CKV_TYPE_HARDWARE: u32 = 2; -pub const CKV_TYPE_FIRMWARE: u32 = 3; -pub const CKV_TYPE_HYBRID: u32 = 4; +pub const CKV_AUTHORITY_TYPE_UNSPECIFIED: CK_ULONG = 0; +pub const CKV_AUTHORITY_TYPE_NIST_CMVP: CK_ULONG = 1; +pub const CKV_AUTHORITY_TYPE_COMMON_CRITERIA: CK_ULONG = 2; +pub const CKV_TYPE_UNSPECIFIED: CK_ULONG = 0; +pub const CKV_TYPE_SOFTWARE: CK_ULONG = 1; +pub const CKV_TYPE_HARDWARE: CK_ULONG = 2; +pub const CKV_TYPE_FIRMWARE: CK_ULONG = 3; +pub const CKV_TYPE_HYBRID: CK_ULONG = 4; pub const CKZ_DATA_SPECIFIED: CK_RSA_PKCS_OAEP_SOURCE_TYPE = 1; pub const CKZ_SALT_SPECIFIED: CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE = 1; pub type CK_BBOOL = ::std::os::raw::c_uchar; diff --git a/cryptoki-sys/src/bindings/aarch64-unknown-linux-gnu.rs b/cryptoki-sys/src/bindings/aarch64-unknown-linux-gnu.rs index dc7c75e2..dad0c585 100644 --- a/cryptoki-sys/src/bindings/aarch64-unknown-linux-gnu.rs +++ b/cryptoki-sys/src/bindings/aarch64-unknown-linux-gnu.rs @@ -1039,14 +1039,14 @@ pub const CKT_TRUST_MUST_VERIFY_TRUST: u32 = 4; pub const CKU_SO: CK_USER_TYPE = 0; pub const CKU_USER: CK_USER_TYPE = 1; pub const CKU_CONTEXT_SPECIFIC: CK_USER_TYPE = 2; -pub const CKV_AUTHORITY_TYPE_UNSPECIFIED: u32 = 0; -pub const CKV_AUTHORITY_TYPE_NIST_CMVP: u32 = 1; -pub const CKV_AUTHORITY_TYPE_COMMON_CRITERIA: u32 = 2; -pub const CKV_TYPE_UNSPECIFIED: u32 = 0; -pub const CKV_TYPE_SOFTWARE: u32 = 1; -pub const CKV_TYPE_HARDWARE: u32 = 2; -pub const CKV_TYPE_FIRMWARE: u32 = 3; -pub const CKV_TYPE_HYBRID: u32 = 4; +pub const CKV_AUTHORITY_TYPE_UNSPECIFIED: CK_ULONG = 0; +pub const CKV_AUTHORITY_TYPE_NIST_CMVP: CK_ULONG = 1; +pub const CKV_AUTHORITY_TYPE_COMMON_CRITERIA: CK_ULONG = 2; +pub const CKV_TYPE_UNSPECIFIED: CK_ULONG = 0; +pub const CKV_TYPE_SOFTWARE: CK_ULONG = 1; +pub const CKV_TYPE_HARDWARE: CK_ULONG = 2; +pub const CKV_TYPE_FIRMWARE: CK_ULONG = 3; +pub const CKV_TYPE_HYBRID: CK_ULONG = 4; pub const CKZ_DATA_SPECIFIED: CK_RSA_PKCS_OAEP_SOURCE_TYPE = 1; pub const CKZ_SALT_SPECIFIED: CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE = 1; pub type CK_BBOOL = ::std::os::raw::c_uchar; diff --git a/cryptoki-sys/src/bindings/arm-unknown-linux-gnueabi.rs b/cryptoki-sys/src/bindings/arm-unknown-linux-gnueabi.rs index f24ab486..6dc605be 100644 --- a/cryptoki-sys/src/bindings/arm-unknown-linux-gnueabi.rs +++ b/cryptoki-sys/src/bindings/arm-unknown-linux-gnueabi.rs @@ -1039,14 +1039,14 @@ pub const CKT_TRUST_MUST_VERIFY_TRUST: u32 = 4; pub const CKU_SO: CK_USER_TYPE = 0; pub const CKU_USER: CK_USER_TYPE = 1; pub const CKU_CONTEXT_SPECIFIC: CK_USER_TYPE = 2; -pub const CKV_AUTHORITY_TYPE_UNSPECIFIED: u32 = 0; -pub const CKV_AUTHORITY_TYPE_NIST_CMVP: u32 = 1; -pub const CKV_AUTHORITY_TYPE_COMMON_CRITERIA: u32 = 2; -pub const CKV_TYPE_UNSPECIFIED: u32 = 0; -pub const CKV_TYPE_SOFTWARE: u32 = 1; -pub const CKV_TYPE_HARDWARE: u32 = 2; -pub const CKV_TYPE_FIRMWARE: u32 = 3; -pub const CKV_TYPE_HYBRID: u32 = 4; +pub const CKV_AUTHORITY_TYPE_UNSPECIFIED: CK_ULONG = 0; +pub const CKV_AUTHORITY_TYPE_NIST_CMVP: CK_ULONG = 1; +pub const CKV_AUTHORITY_TYPE_COMMON_CRITERIA: CK_ULONG = 2; +pub const CKV_TYPE_UNSPECIFIED: CK_ULONG = 0; +pub const CKV_TYPE_SOFTWARE: CK_ULONG = 1; +pub const CKV_TYPE_HARDWARE: CK_ULONG = 2; +pub const CKV_TYPE_FIRMWARE: CK_ULONG = 3; +pub const CKV_TYPE_HYBRID: CK_ULONG = 4; pub const CKZ_DATA_SPECIFIED: CK_RSA_PKCS_OAEP_SOURCE_TYPE = 1; pub const CKZ_SALT_SPECIFIED: CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE = 1; pub type CK_BBOOL = ::std::os::raw::c_uchar; diff --git a/cryptoki-sys/src/bindings/generic.rs b/cryptoki-sys/src/bindings/generic.rs index 33cde7bd..028b4e14 100644 --- a/cryptoki-sys/src/bindings/generic.rs +++ b/cryptoki-sys/src/bindings/generic.rs @@ -1039,14 +1039,14 @@ pub const CKT_TRUST_MUST_VERIFY_TRUST: u32 = 4; pub const CKU_SO: CK_USER_TYPE = 0; pub const CKU_USER: CK_USER_TYPE = 1; pub const CKU_CONTEXT_SPECIFIC: CK_USER_TYPE = 2; -pub const CKV_AUTHORITY_TYPE_UNSPECIFIED: u32 = 0; -pub const CKV_AUTHORITY_TYPE_NIST_CMVP: u32 = 1; -pub const CKV_AUTHORITY_TYPE_COMMON_CRITERIA: u32 = 2; -pub const CKV_TYPE_UNSPECIFIED: u32 = 0; -pub const CKV_TYPE_SOFTWARE: u32 = 1; -pub const CKV_TYPE_HARDWARE: u32 = 2; -pub const CKV_TYPE_FIRMWARE: u32 = 3; -pub const CKV_TYPE_HYBRID: u32 = 4; +pub const CKV_AUTHORITY_TYPE_UNSPECIFIED: CK_ULONG = 0; +pub const CKV_AUTHORITY_TYPE_NIST_CMVP: CK_ULONG = 1; +pub const CKV_AUTHORITY_TYPE_COMMON_CRITERIA: CK_ULONG = 2; +pub const CKV_TYPE_UNSPECIFIED: CK_ULONG = 0; +pub const CKV_TYPE_SOFTWARE: CK_ULONG = 1; +pub const CKV_TYPE_HARDWARE: CK_ULONG = 2; +pub const CKV_TYPE_FIRMWARE: CK_ULONG = 3; +pub const CKV_TYPE_HYBRID: CK_ULONG = 4; pub const CKZ_DATA_SPECIFIED: CK_RSA_PKCS_OAEP_SOURCE_TYPE = 1; pub const CKZ_SALT_SPECIFIED: CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE = 1; pub type CK_BBOOL = ::std::os::raw::c_uchar; diff --git a/cryptoki-sys/src/bindings/i686-unknown-linux-gnu.rs b/cryptoki-sys/src/bindings/i686-unknown-linux-gnu.rs index f24ab486..6dc605be 100644 --- a/cryptoki-sys/src/bindings/i686-unknown-linux-gnu.rs +++ b/cryptoki-sys/src/bindings/i686-unknown-linux-gnu.rs @@ -1039,14 +1039,14 @@ pub const CKT_TRUST_MUST_VERIFY_TRUST: u32 = 4; pub const CKU_SO: CK_USER_TYPE = 0; pub const CKU_USER: CK_USER_TYPE = 1; pub const CKU_CONTEXT_SPECIFIC: CK_USER_TYPE = 2; -pub const CKV_AUTHORITY_TYPE_UNSPECIFIED: u32 = 0; -pub const CKV_AUTHORITY_TYPE_NIST_CMVP: u32 = 1; -pub const CKV_AUTHORITY_TYPE_COMMON_CRITERIA: u32 = 2; -pub const CKV_TYPE_UNSPECIFIED: u32 = 0; -pub const CKV_TYPE_SOFTWARE: u32 = 1; -pub const CKV_TYPE_HARDWARE: u32 = 2; -pub const CKV_TYPE_FIRMWARE: u32 = 3; -pub const CKV_TYPE_HYBRID: u32 = 4; +pub const CKV_AUTHORITY_TYPE_UNSPECIFIED: CK_ULONG = 0; +pub const CKV_AUTHORITY_TYPE_NIST_CMVP: CK_ULONG = 1; +pub const CKV_AUTHORITY_TYPE_COMMON_CRITERIA: CK_ULONG = 2; +pub const CKV_TYPE_UNSPECIFIED: CK_ULONG = 0; +pub const CKV_TYPE_SOFTWARE: CK_ULONG = 1; +pub const CKV_TYPE_HARDWARE: CK_ULONG = 2; +pub const CKV_TYPE_FIRMWARE: CK_ULONG = 3; +pub const CKV_TYPE_HYBRID: CK_ULONG = 4; pub const CKZ_DATA_SPECIFIED: CK_RSA_PKCS_OAEP_SOURCE_TYPE = 1; pub const CKZ_SALT_SPECIFIED: CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE = 1; pub type CK_BBOOL = ::std::os::raw::c_uchar; diff --git a/cryptoki-sys/src/bindings/loongarch64-unknown-linux-gnu.rs b/cryptoki-sys/src/bindings/loongarch64-unknown-linux-gnu.rs index dc7c75e2..dad0c585 100644 --- a/cryptoki-sys/src/bindings/loongarch64-unknown-linux-gnu.rs +++ b/cryptoki-sys/src/bindings/loongarch64-unknown-linux-gnu.rs @@ -1039,14 +1039,14 @@ pub const CKT_TRUST_MUST_VERIFY_TRUST: u32 = 4; pub const CKU_SO: CK_USER_TYPE = 0; pub const CKU_USER: CK_USER_TYPE = 1; pub const CKU_CONTEXT_SPECIFIC: CK_USER_TYPE = 2; -pub const CKV_AUTHORITY_TYPE_UNSPECIFIED: u32 = 0; -pub const CKV_AUTHORITY_TYPE_NIST_CMVP: u32 = 1; -pub const CKV_AUTHORITY_TYPE_COMMON_CRITERIA: u32 = 2; -pub const CKV_TYPE_UNSPECIFIED: u32 = 0; -pub const CKV_TYPE_SOFTWARE: u32 = 1; -pub const CKV_TYPE_HARDWARE: u32 = 2; -pub const CKV_TYPE_FIRMWARE: u32 = 3; -pub const CKV_TYPE_HYBRID: u32 = 4; +pub const CKV_AUTHORITY_TYPE_UNSPECIFIED: CK_ULONG = 0; +pub const CKV_AUTHORITY_TYPE_NIST_CMVP: CK_ULONG = 1; +pub const CKV_AUTHORITY_TYPE_COMMON_CRITERIA: CK_ULONG = 2; +pub const CKV_TYPE_UNSPECIFIED: CK_ULONG = 0; +pub const CKV_TYPE_SOFTWARE: CK_ULONG = 1; +pub const CKV_TYPE_HARDWARE: CK_ULONG = 2; +pub const CKV_TYPE_FIRMWARE: CK_ULONG = 3; +pub const CKV_TYPE_HYBRID: CK_ULONG = 4; pub const CKZ_DATA_SPECIFIED: CK_RSA_PKCS_OAEP_SOURCE_TYPE = 1; pub const CKZ_SALT_SPECIFIED: CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE = 1; pub type CK_BBOOL = ::std::os::raw::c_uchar; diff --git a/cryptoki-sys/src/bindings/powerpc64-unknown-linux-gnu.rs b/cryptoki-sys/src/bindings/powerpc64-unknown-linux-gnu.rs index dc7c75e2..dad0c585 100644 --- a/cryptoki-sys/src/bindings/powerpc64-unknown-linux-gnu.rs +++ b/cryptoki-sys/src/bindings/powerpc64-unknown-linux-gnu.rs @@ -1039,14 +1039,14 @@ pub const CKT_TRUST_MUST_VERIFY_TRUST: u32 = 4; pub const CKU_SO: CK_USER_TYPE = 0; pub const CKU_USER: CK_USER_TYPE = 1; pub const CKU_CONTEXT_SPECIFIC: CK_USER_TYPE = 2; -pub const CKV_AUTHORITY_TYPE_UNSPECIFIED: u32 = 0; -pub const CKV_AUTHORITY_TYPE_NIST_CMVP: u32 = 1; -pub const CKV_AUTHORITY_TYPE_COMMON_CRITERIA: u32 = 2; -pub const CKV_TYPE_UNSPECIFIED: u32 = 0; -pub const CKV_TYPE_SOFTWARE: u32 = 1; -pub const CKV_TYPE_HARDWARE: u32 = 2; -pub const CKV_TYPE_FIRMWARE: u32 = 3; -pub const CKV_TYPE_HYBRID: u32 = 4; +pub const CKV_AUTHORITY_TYPE_UNSPECIFIED: CK_ULONG = 0; +pub const CKV_AUTHORITY_TYPE_NIST_CMVP: CK_ULONG = 1; +pub const CKV_AUTHORITY_TYPE_COMMON_CRITERIA: CK_ULONG = 2; +pub const CKV_TYPE_UNSPECIFIED: CK_ULONG = 0; +pub const CKV_TYPE_SOFTWARE: CK_ULONG = 1; +pub const CKV_TYPE_HARDWARE: CK_ULONG = 2; +pub const CKV_TYPE_FIRMWARE: CK_ULONG = 3; +pub const CKV_TYPE_HYBRID: CK_ULONG = 4; pub const CKZ_DATA_SPECIFIED: CK_RSA_PKCS_OAEP_SOURCE_TYPE = 1; pub const CKZ_SALT_SPECIFIED: CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE = 1; pub type CK_BBOOL = ::std::os::raw::c_uchar; diff --git a/cryptoki-sys/src/bindings/riscv64gc-unknown-linux-gnu.rs b/cryptoki-sys/src/bindings/riscv64gc-unknown-linux-gnu.rs index dc7c75e2..dad0c585 100644 --- a/cryptoki-sys/src/bindings/riscv64gc-unknown-linux-gnu.rs +++ b/cryptoki-sys/src/bindings/riscv64gc-unknown-linux-gnu.rs @@ -1039,14 +1039,14 @@ pub const CKT_TRUST_MUST_VERIFY_TRUST: u32 = 4; pub const CKU_SO: CK_USER_TYPE = 0; pub const CKU_USER: CK_USER_TYPE = 1; pub const CKU_CONTEXT_SPECIFIC: CK_USER_TYPE = 2; -pub const CKV_AUTHORITY_TYPE_UNSPECIFIED: u32 = 0; -pub const CKV_AUTHORITY_TYPE_NIST_CMVP: u32 = 1; -pub const CKV_AUTHORITY_TYPE_COMMON_CRITERIA: u32 = 2; -pub const CKV_TYPE_UNSPECIFIED: u32 = 0; -pub const CKV_TYPE_SOFTWARE: u32 = 1; -pub const CKV_TYPE_HARDWARE: u32 = 2; -pub const CKV_TYPE_FIRMWARE: u32 = 3; -pub const CKV_TYPE_HYBRID: u32 = 4; +pub const CKV_AUTHORITY_TYPE_UNSPECIFIED: CK_ULONG = 0; +pub const CKV_AUTHORITY_TYPE_NIST_CMVP: CK_ULONG = 1; +pub const CKV_AUTHORITY_TYPE_COMMON_CRITERIA: CK_ULONG = 2; +pub const CKV_TYPE_UNSPECIFIED: CK_ULONG = 0; +pub const CKV_TYPE_SOFTWARE: CK_ULONG = 1; +pub const CKV_TYPE_HARDWARE: CK_ULONG = 2; +pub const CKV_TYPE_FIRMWARE: CK_ULONG = 3; +pub const CKV_TYPE_HYBRID: CK_ULONG = 4; pub const CKZ_DATA_SPECIFIED: CK_RSA_PKCS_OAEP_SOURCE_TYPE = 1; pub const CKZ_SALT_SPECIFIED: CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE = 1; pub type CK_BBOOL = ::std::os::raw::c_uchar; diff --git a/cryptoki-sys/src/bindings/x86_64-apple-darwin.rs b/cryptoki-sys/src/bindings/x86_64-apple-darwin.rs index dc7c75e2..dad0c585 100644 --- a/cryptoki-sys/src/bindings/x86_64-apple-darwin.rs +++ b/cryptoki-sys/src/bindings/x86_64-apple-darwin.rs @@ -1039,14 +1039,14 @@ pub const CKT_TRUST_MUST_VERIFY_TRUST: u32 = 4; pub const CKU_SO: CK_USER_TYPE = 0; pub const CKU_USER: CK_USER_TYPE = 1; pub const CKU_CONTEXT_SPECIFIC: CK_USER_TYPE = 2; -pub const CKV_AUTHORITY_TYPE_UNSPECIFIED: u32 = 0; -pub const CKV_AUTHORITY_TYPE_NIST_CMVP: u32 = 1; -pub const CKV_AUTHORITY_TYPE_COMMON_CRITERIA: u32 = 2; -pub const CKV_TYPE_UNSPECIFIED: u32 = 0; -pub const CKV_TYPE_SOFTWARE: u32 = 1; -pub const CKV_TYPE_HARDWARE: u32 = 2; -pub const CKV_TYPE_FIRMWARE: u32 = 3; -pub const CKV_TYPE_HYBRID: u32 = 4; +pub const CKV_AUTHORITY_TYPE_UNSPECIFIED: CK_ULONG = 0; +pub const CKV_AUTHORITY_TYPE_NIST_CMVP: CK_ULONG = 1; +pub const CKV_AUTHORITY_TYPE_COMMON_CRITERIA: CK_ULONG = 2; +pub const CKV_TYPE_UNSPECIFIED: CK_ULONG = 0; +pub const CKV_TYPE_SOFTWARE: CK_ULONG = 1; +pub const CKV_TYPE_HARDWARE: CK_ULONG = 2; +pub const CKV_TYPE_FIRMWARE: CK_ULONG = 3; +pub const CKV_TYPE_HYBRID: CK_ULONG = 4; pub const CKZ_DATA_SPECIFIED: CK_RSA_PKCS_OAEP_SOURCE_TYPE = 1; pub const CKZ_SALT_SPECIFIED: CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE = 1; pub type CK_BBOOL = ::std::os::raw::c_uchar; diff --git a/cryptoki-sys/src/bindings/x86_64-pc-windows-msvc.rs b/cryptoki-sys/src/bindings/x86_64-pc-windows-msvc.rs index 4424235f..2639d566 100644 --- a/cryptoki-sys/src/bindings/x86_64-pc-windows-msvc.rs +++ b/cryptoki-sys/src/bindings/x86_64-pc-windows-msvc.rs @@ -1039,14 +1039,14 @@ pub const CKT_TRUST_MUST_VERIFY_TRUST: u32 = 4; pub const CKU_SO: CK_USER_TYPE = 0; pub const CKU_USER: CK_USER_TYPE = 1; pub const CKU_CONTEXT_SPECIFIC: CK_USER_TYPE = 2; -pub const CKV_AUTHORITY_TYPE_UNSPECIFIED: u32 = 0; -pub const CKV_AUTHORITY_TYPE_NIST_CMVP: u32 = 1; -pub const CKV_AUTHORITY_TYPE_COMMON_CRITERIA: u32 = 2; -pub const CKV_TYPE_UNSPECIFIED: u32 = 0; -pub const CKV_TYPE_SOFTWARE: u32 = 1; -pub const CKV_TYPE_HARDWARE: u32 = 2; -pub const CKV_TYPE_FIRMWARE: u32 = 3; -pub const CKV_TYPE_HYBRID: u32 = 4; +pub const CKV_AUTHORITY_TYPE_UNSPECIFIED: CK_ULONG = 0; +pub const CKV_AUTHORITY_TYPE_NIST_CMVP: CK_ULONG = 1; +pub const CKV_AUTHORITY_TYPE_COMMON_CRITERIA: CK_ULONG = 2; +pub const CKV_TYPE_UNSPECIFIED: CK_ULONG = 0; +pub const CKV_TYPE_SOFTWARE: CK_ULONG = 1; +pub const CKV_TYPE_HARDWARE: CK_ULONG = 2; +pub const CKV_TYPE_FIRMWARE: CK_ULONG = 3; +pub const CKV_TYPE_HYBRID: CK_ULONG = 4; pub const CKZ_DATA_SPECIFIED: CK_RSA_PKCS_OAEP_SOURCE_TYPE = 1; pub const CKZ_SALT_SPECIFIED: CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE = 1; pub type CK_BBOOL = ::std::os::raw::c_uchar; diff --git a/cryptoki-sys/src/bindings/x86_64-unknown-freebsd.rs b/cryptoki-sys/src/bindings/x86_64-unknown-freebsd.rs index dc7c75e2..dad0c585 100644 --- a/cryptoki-sys/src/bindings/x86_64-unknown-freebsd.rs +++ b/cryptoki-sys/src/bindings/x86_64-unknown-freebsd.rs @@ -1039,14 +1039,14 @@ pub const CKT_TRUST_MUST_VERIFY_TRUST: u32 = 4; pub const CKU_SO: CK_USER_TYPE = 0; pub const CKU_USER: CK_USER_TYPE = 1; pub const CKU_CONTEXT_SPECIFIC: CK_USER_TYPE = 2; -pub const CKV_AUTHORITY_TYPE_UNSPECIFIED: u32 = 0; -pub const CKV_AUTHORITY_TYPE_NIST_CMVP: u32 = 1; -pub const CKV_AUTHORITY_TYPE_COMMON_CRITERIA: u32 = 2; -pub const CKV_TYPE_UNSPECIFIED: u32 = 0; -pub const CKV_TYPE_SOFTWARE: u32 = 1; -pub const CKV_TYPE_HARDWARE: u32 = 2; -pub const CKV_TYPE_FIRMWARE: u32 = 3; -pub const CKV_TYPE_HYBRID: u32 = 4; +pub const CKV_AUTHORITY_TYPE_UNSPECIFIED: CK_ULONG = 0; +pub const CKV_AUTHORITY_TYPE_NIST_CMVP: CK_ULONG = 1; +pub const CKV_AUTHORITY_TYPE_COMMON_CRITERIA: CK_ULONG = 2; +pub const CKV_TYPE_UNSPECIFIED: CK_ULONG = 0; +pub const CKV_TYPE_SOFTWARE: CK_ULONG = 1; +pub const CKV_TYPE_HARDWARE: CK_ULONG = 2; +pub const CKV_TYPE_FIRMWARE: CK_ULONG = 3; +pub const CKV_TYPE_HYBRID: CK_ULONG = 4; pub const CKZ_DATA_SPECIFIED: CK_RSA_PKCS_OAEP_SOURCE_TYPE = 1; pub const CKZ_SALT_SPECIFIED: CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE = 1; pub type CK_BBOOL = ::std::os::raw::c_uchar; diff --git a/cryptoki-sys/src/bindings/x86_64-unknown-linux-gnu.rs b/cryptoki-sys/src/bindings/x86_64-unknown-linux-gnu.rs index dc7c75e2..dad0c585 100644 --- a/cryptoki-sys/src/bindings/x86_64-unknown-linux-gnu.rs +++ b/cryptoki-sys/src/bindings/x86_64-unknown-linux-gnu.rs @@ -1039,14 +1039,14 @@ pub const CKT_TRUST_MUST_VERIFY_TRUST: u32 = 4; pub const CKU_SO: CK_USER_TYPE = 0; pub const CKU_USER: CK_USER_TYPE = 1; pub const CKU_CONTEXT_SPECIFIC: CK_USER_TYPE = 2; -pub const CKV_AUTHORITY_TYPE_UNSPECIFIED: u32 = 0; -pub const CKV_AUTHORITY_TYPE_NIST_CMVP: u32 = 1; -pub const CKV_AUTHORITY_TYPE_COMMON_CRITERIA: u32 = 2; -pub const CKV_TYPE_UNSPECIFIED: u32 = 0; -pub const CKV_TYPE_SOFTWARE: u32 = 1; -pub const CKV_TYPE_HARDWARE: u32 = 2; -pub const CKV_TYPE_FIRMWARE: u32 = 3; -pub const CKV_TYPE_HYBRID: u32 = 4; +pub const CKV_AUTHORITY_TYPE_UNSPECIFIED: CK_ULONG = 0; +pub const CKV_AUTHORITY_TYPE_NIST_CMVP: CK_ULONG = 1; +pub const CKV_AUTHORITY_TYPE_COMMON_CRITERIA: CK_ULONG = 2; +pub const CKV_TYPE_UNSPECIFIED: CK_ULONG = 0; +pub const CKV_TYPE_SOFTWARE: CK_ULONG = 1; +pub const CKV_TYPE_HARDWARE: CK_ULONG = 2; +pub const CKV_TYPE_FIRMWARE: CK_ULONG = 3; +pub const CKV_TYPE_HYBRID: CK_ULONG = 4; pub const CKZ_DATA_SPECIFIED: CK_RSA_PKCS_OAEP_SOURCE_TYPE = 1; pub const CKZ_SALT_SPECIFIED: CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE = 1; pub type CK_BBOOL = ::std::os::raw::c_uchar; diff --git a/cryptoki/README.md b/cryptoki/README.md index 77f998d5..590560e4 100644 --- a/cryptoki/README.md +++ b/cryptoki/README.md @@ -52,10 +52,10 @@ pkcs11.initialize(CInitializeArgs::OsThreads)?; let slot = pkcs11.get_slots_with_token()?[0]; // initialize a test token -let so_pin = AuthPin::new("abcdef".into()); +let so_pin = AuthPin::new("abcdef654321".into()); pkcs11.init_token(slot, &so_pin, "Test Token")?; -let user_pin = AuthPin::new("fedcba".into()); +let user_pin = AuthPin::new("fedcba123456".into()); // initialize user PIN { @@ -73,7 +73,7 @@ let pub_key_template = vec![ Attribute::Token(true), Attribute::Private(false), Attribute::PublicExponent(vec![0x01, 0x00, 0x01]), - Attribute::ModulusBits(1024.into()), + Attribute::ModulusBits(2048.into()), ]; let priv_key_template = vec![Attribute::Token(true)]; diff --git a/cryptoki/src/object.rs b/cryptoki/src/object.rs index 69072e95..fe0e6b7d 100644 --- a/cryptoki/src/object.rs +++ b/cryptoki/src/object.rs @@ -4,7 +4,7 @@ use crate::error::{Error, Result}; use crate::mechanism::MechanismType; -use crate::types::{Date, Ulong}; +use crate::types::{Date, Ulong, Version}; use cryptoki_sys::*; use log::error; use std::convert::TryFrom; @@ -92,6 +92,8 @@ pub enum AttributeType { NeverExtractable, /// Object ID ObjectId, + /// Object Validation flags + ObjectValidationFlags, /// DER encoding of the attribute certificate's subject field Owner, /// Algorithm-specific parameter set @@ -136,6 +138,30 @@ pub enum AttributeType { Unwrap, /// Gives the URL where the complete certificate can be obtained Url, + /// Identifier indicating the validation type + ValidationType, + /// Version of the validation standard or specification + ValidationVersion, + /// Validation level, Meaning is Validation type specific + ValidationLevel, + /// How the module is identified in the validation documentation + ValidationModuleId, + /// Flags identifying this validation in sessions and objects + ValidationFlag, + /// Identifies the authority that issues the validation + ValidationAuthorityType, + /// 2 letter ISO country code + ValidationCountry, + /// Identifier of the validation certificate + ValidationCertificateIdentifier, + /// Validation authority URI from which information related to the validation is available. + /// If the Validation Certificate URI is not provided, the validation object SHOULD include + /// a Validation Vendor URI. + ValidationCertificateUri, + /// Validation Vendor URI from which information related to the validation is available. + ValidationVendorUri, + /// Profile used for validation + ValidationProfile, /// Value of the object Value, /// Length in bytes of the value @@ -272,6 +298,24 @@ impl AttributeType { CKA_SEED => String::from(stringify!(CKA_SEED)), CKA_PARAMETER_SET => String::from(stringify!(CKA_PARAMETER_SET)), CKA_PROFILE_ID => String::from(stringify!(CKA_PROFILE_ID)), + CKA_OBJECT_VALIDATION_FLAGS => String::from(stringify!(CKA_OBJECT_VALIDATION_FLAGS)), + CKA_VALIDATION_TYPE => String::from(stringify!(CKA_VALIDATION_TYPE)), + CKA_VALIDATION_VERSION => String::from(stringify!(CKA_VALIDATION_VERSION)), + CKA_VALIDATION_LEVEL => String::from(stringify!(CKA_VALIDATION_LEVEL)), + CKA_VALIDATION_MODULE_ID => String::from(stringify!(CKA_VALIDATION_MODULE_ID)), + CKA_VALIDATION_FLAG => String::from(stringify!(CKA_VALIDATION_FLAG)), + CKA_VALIDATION_AUTHORITY_TYPE => { + String::from(stringify!(CKA_VALIDATION_AUTHORITY_TYPE)) + } + CKA_VALIDATION_COUNTRY => String::from(stringify!(CKA_VALIDATION_COUNTRY)), + CKA_VALIDATION_CERTIFICATE_IDENTIFIER => { + String::from(stringify!(CKA_VALIDATION_CERTIFICATE_IDENTIFIER)) + } + CKA_VALIDATION_CERTIFICATE_URI => { + String::from(stringify!(CKA_VALIDATION_CERTIFICATE_URI)) + } + CKA_VALIDATION_VENDOR_URI => String::from(stringify!(CKA_VALIDATION_VENDOR_URI)), + CKA_VALIDATION_PROFILE => String::from(stringify!(CKA_VALIDATION_PROFILE)), CKA_VENDOR_DEFINED..=CK_ULONG::MAX => { format!("{}_{}", stringify!(CKA_VENDOR_DEFINED), val) } @@ -326,6 +370,7 @@ impl From for CK_ATTRIBUTE_TYPE { AttributeType::Modulus => CKA_MODULUS, AttributeType::ModulusBits => CKA_MODULUS_BITS, AttributeType::NeverExtractable => CKA_NEVER_EXTRACTABLE, + AttributeType::ObjectValidationFlags => CKA_OBJECT_VALIDATION_FLAGS, AttributeType::ObjectId => CKA_OBJECT_ID, AttributeType::Owner => CKA_OWNER, AttributeType::ParameterSet => CKA_PARAMETER_SET, @@ -349,6 +394,17 @@ impl From for CK_ATTRIBUTE_TYPE { AttributeType::UniqueId => CKA_UNIQUE_ID, AttributeType::Unwrap => CKA_UNWRAP, AttributeType::Url => CKA_URL, + AttributeType::ValidationType => CKA_VALIDATION_TYPE, + AttributeType::ValidationVersion => CKA_VALIDATION_VERSION, + AttributeType::ValidationLevel => CKA_VALIDATION_LEVEL, + AttributeType::ValidationModuleId => CKA_VALIDATION_MODULE_ID, + AttributeType::ValidationFlag => CKA_VALIDATION_FLAG, + AttributeType::ValidationAuthorityType => CKA_VALIDATION_AUTHORITY_TYPE, + AttributeType::ValidationCountry => CKA_VALIDATION_COUNTRY, + AttributeType::ValidationCertificateIdentifier => CKA_VALIDATION_CERTIFICATE_IDENTIFIER, + AttributeType::ValidationCertificateUri => CKA_VALIDATION_CERTIFICATE_URI, + AttributeType::ValidationVendorUri => CKA_VALIDATION_VENDOR_URI, + AttributeType::ValidationProfile => CKA_VALIDATION_PROFILE, AttributeType::Value => CKA_VALUE, AttributeType::ValueLen => CKA_VALUE_LEN, AttributeType::VendorDefined(val) => val, @@ -401,6 +457,7 @@ impl TryFrom for AttributeType { CKA_MODULUS => Ok(AttributeType::Modulus), CKA_MODULUS_BITS => Ok(AttributeType::ModulusBits), CKA_NEVER_EXTRACTABLE => Ok(AttributeType::NeverExtractable), + CKA_OBJECT_VALIDATION_FLAGS => Ok(AttributeType::ObjectValidationFlags), CKA_OBJECT_ID => Ok(AttributeType::ObjectId), CKA_OWNER => Ok(AttributeType::Owner), CKA_PARAMETER_SET => Ok(AttributeType::ParameterSet), @@ -424,6 +481,18 @@ impl TryFrom for AttributeType { CKA_UNIQUE_ID => Ok(AttributeType::UniqueId), CKA_UNWRAP => Ok(AttributeType::Unwrap), CKA_URL => Ok(AttributeType::Url), + CKA_VALIDATION_TYPE => Ok(AttributeType::ValidationType), + CKA_VALIDATION_VERSION => Ok(AttributeType::ValidationVersion), + CKA_VALIDATION_LEVEL => Ok(AttributeType::ValidationLevel), + CKA_VALIDATION_MODULE_ID => Ok(AttributeType::ValidationModuleId), + CKA_VALIDATION_FLAG => Ok(AttributeType::ValidationFlag), + CKA_VALIDATION_AUTHORITY_TYPE => Ok(AttributeType::ValidationAuthorityType), + CKA_VALIDATION_COUNTRY => Ok(AttributeType::ValidationCountry), + CKA_VALIDATION_CERTIFICATE_IDENTIFIER => { + Ok(AttributeType::ValidationCertificateIdentifier) + } + CKA_VALIDATION_CERTIFICATE_URI => Ok(AttributeType::ValidationCertificateUri), + CKA_VALIDATION_PROFILE => Ok(AttributeType::ValidationProfile), CKA_VALUE => Ok(AttributeType::Value), CKA_VALUE_LEN => Ok(AttributeType::ValueLen), CKA_VERIFY => Ok(AttributeType::Verify), @@ -515,6 +584,8 @@ pub enum Attribute { ModulusBits(Ulong), /// Indicates if the key has never had the Extractable attribute set to true NeverExtractable(bool), + /// Object Validation Flags + ObjectValidationFlags(Ulong), /// Object ID ObjectId(Vec), /// DER encoding of the attribute certificate's subject field @@ -561,6 +632,29 @@ pub enum Attribute { Unwrap(bool), /// Gives the URL where the complete certificate can ber obtained Url(Vec), + /// Identifier indicating the validation type + ValidationType(ValidationType), + /// Version of the validation standard or specification + ValidationVersion(Version), + /// Validation level, Meaning is Validation type specific + ValidationLevel(Ulong), + /// How the module is identified in the validation documentation + ValidationModuleId(Vec), + /// Flags identifying this validation in sessions and objects + ValidationFlag(Ulong), + /// Identifies the authority that issues the validation + ValidationAuthorityType(ValidationAuthorityType), + /// 2 letter ISO country code + ValidationCountry(Vec), + /// Identifier of the validation certificate + ValidationCertificateIdentifier(Vec), + /// Validation authority URI from which information related to the validation is available. If the Validation + /// Certificate URI is not provided, the validation object SHOULD include a Validation Vendor URI. + ValidationCertificateUri(Vec), + /// Validation Vendor URI from which information related to the validation is available. + ValidationVendorUri(Vec), + /// Profile used for validation + ValidationProfile(Vec), /// Value of the object Value(Vec), /// Length in bytes of the value @@ -617,6 +711,7 @@ impl Attribute { Attribute::Modulus(_) => AttributeType::Modulus, Attribute::ModulusBits(_) => AttributeType::ModulusBits, Attribute::NeverExtractable(_) => AttributeType::NeverExtractable, + Attribute::ObjectValidationFlags(_) => AttributeType::ObjectValidationFlags, Attribute::ObjectId(_) => AttributeType::ObjectId, Attribute::Owner(_) => AttributeType::Owner, Attribute::ParameterSet(_) => AttributeType::ParameterSet, @@ -640,6 +735,19 @@ impl Attribute { Attribute::UniqueId(_) => AttributeType::UniqueId, Attribute::Unwrap(_) => AttributeType::Unwrap, Attribute::Url(_) => AttributeType::Url, + Attribute::ValidationType(_) => AttributeType::ValidationType, + Attribute::ValidationVersion(_) => AttributeType::ValidationVersion, + Attribute::ValidationLevel(_) => AttributeType::ValidationLevel, + Attribute::ValidationModuleId(_) => AttributeType::ValidationModuleId, + Attribute::ValidationFlag(_) => AttributeType::ValidationFlag, + Attribute::ValidationAuthorityType(_) => AttributeType::ValidationAuthorityType, + Attribute::ValidationCountry(_) => AttributeType::ValidationCountry, + Attribute::ValidationCertificateIdentifier(_) => { + AttributeType::ValidationCertificateIdentifier + } + Attribute::ValidationCertificateUri(_) => AttributeType::ValidationCertificateUri, + Attribute::ValidationVendorUri(_) => AttributeType::ValidationVendorUri, + Attribute::ValidationProfile(_) => AttributeType::ValidationProfile, Attribute::Value(_) => AttributeType::Value, Attribute::ValueLen(_) => AttributeType::ValueLen, Attribute::VendorDefined((num, _)) => *num, @@ -678,9 +786,15 @@ impl Attribute { | Attribute::Wrap(_) | Attribute::WrapWithTrusted(_) => size_of::(), Attribute::Base(_) => 1, - Attribute::Application(bytes) | Attribute::Label(bytes) | Attribute::Url(bytes) => { - size_of::() * bytes.len() - } + Attribute::Application(bytes) + | Attribute::Label(bytes) + | Attribute::Url(bytes) + | Attribute::ValidationModuleId(bytes) + | Attribute::ValidationCountry(bytes) + | Attribute::ValidationCertificateIdentifier(bytes) + | Attribute::ValidationCertificateUri(bytes) + | Attribute::ValidationVendorUri(bytes) + | Attribute::ValidationProfile(bytes) => size_of::() * bytes.len(), Attribute::AcIssuer(bytes) => bytes.len(), Attribute::AttrTypes(bytes) => bytes.len(), Attribute::CertificateType(_) => size_of::(), @@ -699,6 +813,7 @@ impl Attribute { Attribute::KeyType(_) => size_of::(), Attribute::Modulus(bytes) => bytes.len(), Attribute::ModulusBits(_) => size_of::(), + Attribute::ObjectValidationFlags(_) => size_of::(), Attribute::ObjectId(bytes) => bytes.len(), Attribute::Owner(bytes) => bytes.len(), Attribute::ParameterSet(_) => size_of::(), @@ -713,6 +828,11 @@ impl Attribute { Attribute::SerialNumber(bytes) => bytes.len(), Attribute::Subject(bytes) => bytes.len(), Attribute::UniqueId(bytes) => bytes.len(), + Attribute::ValidationFlag(_) => size_of::(), + Attribute::ValidationType(_) => size_of::(), + Attribute::ValidationVersion(_) => size_of::(), + Attribute::ValidationLevel(_) => size_of::(), + Attribute::ValidationAuthorityType(_) => size_of::(), Attribute::Value(bytes) => bytes.len(), Attribute::ValueLen(_) => size_of::(), Attribute::EndDate(_) | Attribute::StartDate(_) => size_of::(), @@ -764,9 +884,10 @@ impl Attribute { | Attribute::Wrap(b) | Attribute::WrapWithTrusted(b) => b as *const _ as *mut c_void, // CK_ULONG - Attribute::ModulusBits(val) | Attribute::ValueLen(val) => { - val as *const _ as *mut c_void - } + Attribute::ModulusBits(val) + | Attribute::ValueLen(val) + | Attribute::ObjectValidationFlags(val) + | Attribute::ValidationLevel(val) => val as *const _ as *mut c_void, // Vec Attribute::AcIssuer(bytes) | Attribute::Application(bytes) @@ -797,6 +918,12 @@ impl Attribute { | Attribute::UniqueId(bytes) | Attribute::Url(bytes) | Attribute::Value(bytes) + | Attribute::ValidationModuleId(bytes) + | Attribute::ValidationCountry(bytes) + | Attribute::ValidationCertificateIdentifier(bytes) + | Attribute::ValidationCertificateUri(bytes) + | Attribute::ValidationVendorUri(bytes) + | Attribute::ValidationProfile(bytes) | Attribute::VendorDefined((_, bytes)) | Attribute::Id(bytes) => bytes.as_ptr() as *mut c_void, // Unique types @@ -808,6 +935,14 @@ impl Attribute { Attribute::Class(object_class) => object_class as *const _ as *mut c_void, Attribute::KeyGenMechanism(mech) => mech as *const _ as *mut c_void, Attribute::KeyType(key_type) => key_type as *const _ as *mut c_void, + Attribute::ValidationFlag(flag) => flag as *const _ as *mut c_void, + Attribute::ValidationType(validation_type) => { + validation_type as *const _ as *mut c_void + } + Attribute::ValidationVersion(version) => version as *const _ as *mut c_void, + Attribute::ValidationAuthorityType(authority_type) => { + authority_type as *const _ as *mut c_void + } Attribute::AllowedMechanisms(mechanisms) => mechanisms.as_ptr() as *mut c_void, Attribute::EndDate(date) | Attribute::StartDate(date) => { date as *const _ as *mut c_void @@ -896,6 +1031,15 @@ impl TryFrom for Attribute { AttributeType::ValueLen => Ok(Attribute::ValueLen( CK_ULONG::from_ne_bytes(val.try_into()?).into(), )), + AttributeType::ObjectValidationFlags => Ok(Attribute::ObjectValidationFlags( + CK_ULONG::from_ne_bytes(val.try_into()?).into(), + )), + AttributeType::ValidationLevel => Ok(Attribute::ValidationLevel( + CK_ULONG::from_ne_bytes(val.try_into()?).into(), + )), + AttributeType::ValidationFlag => Ok(Attribute::ValidationFlag( + CK_ULONG::from_ne_bytes(val.try_into()?).into(), + )), // Vec AttributeType::AcIssuer => Ok(Attribute::AcIssuer(val.to_vec())), AttributeType::Application => Ok(Attribute::Application(val.to_vec())), @@ -929,6 +1073,16 @@ impl TryFrom for Attribute { AttributeType::Subject => Ok(Attribute::Subject(val.to_vec())), AttributeType::UniqueId => Ok(Attribute::UniqueId(val.to_vec())), AttributeType::Url => Ok(Attribute::Url(val.to_vec())), + AttributeType::ValidationModuleId => Ok(Attribute::ValidationModuleId(val.to_vec())), + AttributeType::ValidationCountry => Ok(Attribute::ValidationCountry(val.to_vec())), + AttributeType::ValidationCertificateIdentifier => { + Ok(Attribute::ValidationCertificateIdentifier(val.to_vec())) + } + AttributeType::ValidationCertificateUri => { + Ok(Attribute::ValidationCertificateUri(val.to_vec())) + } + AttributeType::ValidationVendorUri => Ok(Attribute::ValidationVendorUri(val.to_vec())), + AttributeType::ValidationProfile => Ok(Attribute::ValidationProfile(val.to_vec())), AttributeType::Value => Ok(Attribute::Value(val.to_vec())), AttributeType::Id => Ok(Attribute::Id(val.to_vec())), // Unique types @@ -950,6 +1104,15 @@ impl TryFrom for Attribute { AttributeType::KeyType => Ok(Attribute::KeyType( CK_KEY_TYPE::from_ne_bytes(val.try_into()?).try_into()?, )), + AttributeType::ValidationType => Ok(Attribute::ValidationType( + CK_VALIDATION_TYPE::from_ne_bytes(val.try_into()?).try_into()?, + )), + AttributeType::ValidationAuthorityType => Ok(Attribute::ValidationAuthorityType( + CK_VALIDATION_AUTHORITY_TYPE::from_ne_bytes(val.try_into()?).try_into()?, + )), + AttributeType::ValidationVersion => { + Ok(Attribute::ValidationVersion(Version::new(val[0], val[1]))) + } AttributeType::AllowedMechanisms => { let val = unsafe { std::slice::from_raw_parts( @@ -1956,3 +2119,160 @@ impl TryFrom for ProfileIdType { } } } + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[repr(transparent)] +/// The PKCS#11 3.2 Validation Type +/// +/// identifies the type of validation +pub struct ValidationType { + val: CK_VALIDATION_TYPE, +} + +impl ValidationType { + /// Unspecified validation type + pub const UNSPECIFIED: ValidationType = ValidationType { + val: CKV_TYPE_UNSPECIFIED, + }; + /// Software validation type + pub const SOFTWARE: ValidationType = ValidationType { + val: CKV_TYPE_SOFTWARE, + }; + /// Hardware validation type + pub const HARDWARE: ValidationType = ValidationType { + val: CKV_TYPE_HARDWARE, + }; + /// Firmware validation type + pub const FIRMWARE: ValidationType = ValidationType { + val: CKV_TYPE_FIRMWARE, + }; + /// Hybrid validation type + pub const HYBRID: ValidationType = ValidationType { + val: CKV_TYPE_HYBRID, + }; + + pub(crate) fn stringify(validation_type: CK_VALIDATION_TYPE) -> String { + match validation_type { + CKV_TYPE_UNSPECIFIED => String::from(stringify!(CKV_TYPE_UNSPECIFIED)), + CKV_TYPE_SOFTWARE => String::from(stringify!(CKV_TYPE_SOFTWARE)), + CKV_TYPE_HARDWARE => String::from(stringify!(CKV_TYPE_HARDWARE)), + CKV_TYPE_FIRMWARE => String::from(stringify!(CKV_TYPE_FIRMWARE)), + CKV_TYPE_HYBRID => String::from(stringify!(CKV_TYPE_HYBRID)), + _ => format!("unknown ({validation_type:08x})"), + } + } +} + +impl std::fmt::Display for ValidationType { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", ValidationType::stringify(self.val)) + } +} + +impl Deref for ValidationType { + type Target = CK_VALIDATION_TYPE; + + fn deref(&self) -> &Self::Target { + &self.val + } +} + +impl From for CK_VALIDATION_TYPE { + fn from(validation_type: ValidationType) -> Self { + *validation_type + } +} + +impl TryFrom for ValidationType { + type Error = Error; + + fn try_from(validation_type: CK_VALIDATION_TYPE) -> Result { + match validation_type { + CKV_TYPE_UNSPECIFIED => Ok(ValidationType::UNSPECIFIED), + CKV_TYPE_SOFTWARE => Ok(ValidationType::SOFTWARE), + CKV_TYPE_HARDWARE => Ok(ValidationType::HARDWARE), + CKV_TYPE_FIRMWARE => Ok(ValidationType::FIRMWARE), + CKV_TYPE_HYBRID => Ok(ValidationType::HYBRID), + _ => { + error!("Validation type {} is not supported.", validation_type); + Err(Error::NotSupported) + } + } + } +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[repr(transparent)] +/// The PKCS#11 3.2 Validation Authority Type +/// +/// identifies the type of validation authority +pub struct ValidationAuthorityType { + val: CK_VALIDATION_AUTHORITY_TYPE, +} + +impl ValidationAuthorityType { + /// Unspecified validation authority type + pub const UNSPECIFIED: ValidationAuthorityType = ValidationAuthorityType { + val: CKV_AUTHORITY_TYPE_UNSPECIFIED, + }; + /// NIST CMVP validation authority type + pub const NIST_CMVP: ValidationAuthorityType = ValidationAuthorityType { + val: CKV_AUTHORITY_TYPE_NIST_CMVP, + }; + /// Common Criteria validation authority type + pub const COMMON_CRITERIA: ValidationAuthorityType = ValidationAuthorityType { + val: CKV_AUTHORITY_TYPE_COMMON_CRITERIA, + }; + + pub(crate) fn stringify(authority_type: CK_VALIDATION_AUTHORITY_TYPE) -> String { + match authority_type { + CKV_AUTHORITY_TYPE_UNSPECIFIED => { + String::from(stringify!(CKV_AUTHORITY_TYPE_UNSPECIFIED)) + } + CKV_AUTHORITY_TYPE_NIST_CMVP => String::from(stringify!(CKV_AUTHORITY_TYPE_NIST_CMVP)), + CKV_AUTHORITY_TYPE_COMMON_CRITERIA => { + String::from(stringify!(CKV_AUTHORITY_TYPE_COMMON_CRITERIA)) + } + _ => format!("unknown ({authority_type:08x})"), + } + } +} + +impl std::fmt::Display for ValidationAuthorityType { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", ValidationAuthorityType::stringify(self.val)) + } +} + +impl Deref for ValidationAuthorityType { + type Target = CK_VALIDATION_AUTHORITY_TYPE; + + fn deref(&self) -> &Self::Target { + &self.val + } +} + +impl From for CK_VALIDATION_AUTHORITY_TYPE { + fn from(validation_type: ValidationAuthorityType) -> Self { + *validation_type + } +} + +impl TryFrom for ValidationAuthorityType { + type Error = Error; + + fn try_from(authority_type: CK_VALIDATION_AUTHORITY_TYPE) -> Result { + match authority_type { + CKV_AUTHORITY_TYPE_UNSPECIFIED => Ok(ValidationAuthorityType::UNSPECIFIED), + CKV_AUTHORITY_TYPE_NIST_CMVP => Ok(ValidationAuthorityType::NIST_CMVP), + CKV_AUTHORITY_TYPE_COMMON_CRITERIA => Ok(ValidationAuthorityType::COMMON_CRITERIA), + _ => { + error!( + "Validation Authority type {} is not supported.", + authority_type + ); + Err(Error::NotSupported) + } + } + } +} diff --git a/cryptoki/src/session/mod.rs b/cryptoki/src/session/mod.rs index c8ec7bb4..119e73d0 100644 --- a/cryptoki/src/session/mod.rs +++ b/cryptoki/src/session/mod.rs @@ -21,9 +21,11 @@ mod session_info; mod session_management; mod signing_macing; mod slot_token_management; +mod validation; pub use object_management::ObjectHandleIterator; pub use session_info::{SessionInfo, SessionState}; +pub use validation::ValidationFlagsType; /// Type that identifies a session /// diff --git a/cryptoki/src/session/object_management.rs b/cryptoki/src/session/object_management.rs index 95ea7db7..e5cf7582 100644 --- a/cryptoki/src/session/object_management.rs +++ b/cryptoki/src/session/object_management.rs @@ -410,7 +410,7 @@ impl Session { /// let slot = pkcs11.get_slots_with_token().unwrap().remove(0); /// /// let session = pkcs11.open_ro_session(slot).unwrap(); - /// session.login(UserType::User, Some(&AuthPin::new("fedcba".into()))); + /// session.login(UserType::User, Some(&AuthPin::new("fedcba123456".into()))); /// /// let empty_attrib= vec![]; /// if let Some(object) = session.find_objects(&empty_attrib).unwrap().first() { diff --git a/cryptoki/src/session/validation.rs b/cryptoki/src/session/validation.rs new file mode 100644 index 00000000..69db3984 --- /dev/null +++ b/cryptoki/src/session/validation.rs @@ -0,0 +1,65 @@ +// Copyright 2025 Contributors to the Parsec project. +// SPDX-License-Identifier: Apache-2.0 +//! Session Validation + +use crate::context::Function; +use crate::error::{Result, Rv}; +use crate::session::Session; +use cryptoki_sys::*; +use std::fmt::{Debug, Formatter}; + +/// The type of validation flag to query +#[derive(Copy, Clone, Debug)] +pub struct ValidationFlagsType { + val: CK_SESSION_VALIDATION_FLAGS_TYPE, +} + +impl ValidationFlagsType { + /// Check the last operation met all requirements of a validated mechanism. + pub const VALIDATION_OK: ValidationFlagsType = ValidationFlagsType { + val: CKS_LAST_VALIDATION_OK, + }; +} + +impl std::fmt::Display for ValidationFlagsType { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!( + f, + "{}", + match self.val { + CKS_LAST_VALIDATION_OK => stringify!(CKS_LAST_VALIDATION_OK), + flags => return write!(f, "unknown ({flags:08x})"), + } + ) + } +} + +impl AsRef for ValidationFlagsType { + fn as_ref(&self) -> &CK_SESSION_VALIDATION_FLAGS_TYPE { + &self.val + } +} + +impl From for CK_SESSION_VALIDATION_FLAGS_TYPE { + fn from(val: ValidationFlagsType) -> Self { + *val.as_ref() + } +} + +impl Session { + /// Get requested validation flags from the session + /// + /// The only supported flag as for PKCS#11 3.2 is `ValidationFlagsType::VALIDATION_OK` + pub fn get_validation_flags(&self, flags_type: ValidationFlagsType) -> Result { + let mut flags: CK_FLAGS = 0; + unsafe { + Rv::from(get_pkcs11!(self.client(), C_GetSessionValidationFlags)( + self.handle(), + flags_type.into(), + &mut flags, + )) + .into_result(Function::GetSessionValidationFlags)?; + } + Ok(flags) + } +} diff --git a/cryptoki/src/types.rs b/cryptoki/src/types.rs index dd9c6f12..46354be9 100644 --- a/cryptoki/src/types.rs +++ b/cryptoki/src/types.rs @@ -192,7 +192,6 @@ impl std::fmt::Display for Version { impl Version { /// Construct a new version - #[cfg(test)] pub(crate) fn new(major: u8, minor: u8) -> Self { Self { major, minor } } diff --git a/cryptoki/tests/basic.rs b/cryptoki/tests/basic.rs index a54b5d4a..9d97d0df 100644 --- a/cryptoki/tests/basic.rs +++ b/cryptoki/tests/basic.rs @@ -2,7 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 mod common; -use crate::common::{get_firmware_version, get_pkcs11, is_kryoptic, is_softhsm, SO_PIN, USER_PIN}; +use crate::common::{ + get_firmware_version, get_pkcs11, is_fips, is_kryoptic, is_softhsm, SO_PIN, USER_PIN, +}; use common::init_pins; use cryptoki::context::Function; use cryptoki::error::{Error, RvError}; @@ -45,7 +47,7 @@ fn sign_verify() -> TestResult { let mechanism = Mechanism::RsaPkcsKeyPairGen; let public_exponent: Vec = vec![0x01, 0x00, 0x01]; - let modulus_bits = 1024; + let modulus_bits = 2048; // pub key template let pub_key_template = vec![ @@ -231,7 +233,7 @@ fn sign_verify_multipart() -> TestResult { // Define parameters for keypair let public_exponent = vec![0x01, 0x00, 0x01]; - let modulus_bits = 1024; + let modulus_bits = 2048; let pub_key_template = vec![ Attribute::Token(true), @@ -340,7 +342,7 @@ fn sign_verify_multipart_already_initialized() -> TestResult { // Define parameters for keypair let public_exponent = vec![0x01, 0x00, 0x01]; - let modulus_bits = 1024; + let modulus_bits = 2048; let pub_key_template = vec![ Attribute::Token(true), @@ -398,6 +400,11 @@ fn encrypt_decrypt() -> TestResult { // open a session let session = pkcs11.open_rw_session(slot)?; + if is_fips(&session) { + eprintln!("The RSA PKCS#1 encryption is not allowed in FIPS Mode"); + return Ok(()); + } + // log in the session session.login(UserType::User, Some(&AuthPin::new(USER_PIN.into())))?; @@ -405,7 +412,7 @@ fn encrypt_decrypt() -> TestResult { let mechanism = Mechanism::RsaPkcsKeyPairGen; let public_exponent: Vec = vec![0x01, 0x00, 0x01]; - let modulus_bits = 1024; + let modulus_bits = 2048; // pub key template let pub_key_template = vec![ @@ -993,6 +1000,11 @@ fn wrap_and_unwrap_key() { // open a session let session = pkcs11.open_rw_session(slot).unwrap(); + if is_fips(&session) { + eprintln!("The RSA PKCS#1 encryption is not allowed in FIPS Mode"); + return; + } + // log in the session session .login(UserType::User, Some(&AuthPin::new(USER_PIN.into()))) @@ -1025,7 +1037,7 @@ fn wrap_and_unwrap_key() { Attribute::Token(true), Attribute::Private(true), Attribute::PublicExponent(vec![0x01, 0x00, 0x01]), - Attribute::ModulusBits(1024.into()), + Attribute::ModulusBits(2048.into()), // key needs to have "wrap" attribute to wrap other keys Attribute::Wrap(true), ]; @@ -1044,7 +1056,7 @@ fn wrap_and_unwrap_key() { let wrapped_key = session .wrap_key(&Mechanism::RsaPkcs, wrapping_key, key_to_be_wrapped) .unwrap(); - assert_eq!(wrapped_key.len(), 128); + assert_eq!(wrapped_key.len(), 256); let unwrapped_key = session .unwrap_key( @@ -1071,6 +1083,100 @@ fn wrap_and_unwrap_key() { assert_eq!(encrypted_with_original, encrypted_with_unwrapped); } +#[test] +#[serial] +fn wrap_and_unwrap_key_oaep() { + let (pkcs11, slot) = init_pins(); + // open a session + let session = pkcs11.open_rw_session(slot).unwrap(); + + // log in the session + session + .login(UserType::User, Some(&AuthPin::new(USER_PIN.into()))) + .unwrap(); + + let key_to_be_wrapped_template = vec![ + Attribute::Token(true), + Attribute::ValueLen(32.into()), + // the key needs to be extractable to be suitable for being wrapped + Attribute::Extractable(true), + Attribute::Encrypt(true), + ]; + + // generate a secret key that will be wrapped + let key_to_be_wrapped = session + .generate_key(&Mechanism::AesKeyGen, &key_to_be_wrapped_template) + .unwrap(); + + // AesEcb input length must be a multiple of 16 + let encrypted_with_original = session + .encrypt( + &Mechanism::AesEcb, + key_to_be_wrapped, + &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], + ) + .unwrap(); + + // pub key template + let pub_key_template = vec![ + Attribute::Token(true), + Attribute::Private(true), + Attribute::PublicExponent(vec![0x01, 0x00, 0x01]), + Attribute::ModulusBits(2048.into()), + // key needs to have "wrap" attribute to wrap other keys + Attribute::Wrap(true), + ]; + + // priv key template + let priv_key_template = vec![Attribute::Token(true), (Attribute::Unwrap(true))]; + + let (wrapping_key, unwrapping_key) = session + .generate_key_pair( + &Mechanism::RsaPkcsKeyPairGen, + &pub_key_template, + &priv_key_template, + ) + .unwrap(); + + let oaep = PkcsOaepParams::new( + MechanismType::SHA1, + PkcsMgfType::MGF1_SHA1, + PkcsOaepSource::empty(), + ); + let wrapped_key = session + .wrap_key( + &Mechanism::RsaPkcsOaep(oaep), + wrapping_key, + key_to_be_wrapped, + ) + .unwrap(); + assert_eq!(wrapped_key.len(), 256); + + let unwrapped_key = session + .unwrap_key( + &Mechanism::RsaPkcsOaep(oaep), + unwrapping_key, + &wrapped_key, + &[ + Attribute::Token(true), + Attribute::Private(true), + Attribute::Encrypt(true), + Attribute::Class(ObjectClass::SECRET_KEY), + Attribute::KeyType(KeyType::AES), + ], + ) + .unwrap(); + + let encrypted_with_unwrapped = session + .encrypt( + &Mechanism::AesEcb, + unwrapped_key, + &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], + ) + .unwrap(); + assert_eq!(encrypted_with_original, encrypted_with_unwrapped); +} + #[test] #[serial] fn login_feast() { @@ -1230,7 +1336,7 @@ fn generate_random_test() -> TestResult { #[test] #[serial] fn set_pin_test() -> TestResult { - let new_user_pin = "123456"; + let new_user_pin = "123456abcdef"; let (pkcs11, slot) = init_pins(); let session = pkcs11.open_rw_session(slot)?; @@ -1665,7 +1771,7 @@ fn update_attributes_key() -> TestResult { Attribute::Token(true), Attribute::Private(true), Attribute::PublicExponent(vec![0x01, 0x00, 0x01]), - Attribute::ModulusBits(1024.into()), + Attribute::ModulusBits(2048.into()), ]; // priv key template @@ -2283,9 +2389,9 @@ fn kbkdf_counter_mode() -> TestResult { // Some variables we will use throughout let counter_format = KbkdfCounterFormat::new(Endianness::Big, NonZeroUsize::new(16).unwrap()); let dkm_length_format = KbkdfDkmLengthFormat::new( - KbkdfDkmLengthMethod::SumOfKeys, + KbkdfDkmLengthMethod::SumOfSegments, Endianness::Big, - NonZeroUsize::new(16).unwrap(), + NonZeroUsize::new(32).unwrap(), ); // Instantiate KBKDF in counter-mode without additional keys @@ -2378,7 +2484,7 @@ fn kbkdf_feedback_mode() -> TestResult { let dkm_length_format = KbkdfDkmLengthFormat::new( KbkdfDkmLengthMethod::SumOfKeys, Endianness::Big, - NonZeroUsize::new(16).unwrap(), + NonZeroUsize::new(32).unwrap(), ); /* FEEDBACK-MODE - no IV */ @@ -2405,12 +2511,8 @@ fn kbkdf_feedback_mode() -> TestResult { PrfDataParam::new(PrfDataParamType::IterationVariable(None)), PrfDataParam::new(PrfDataParamType::Counter(&counter_format)), ]; - let params = KbkdfFeedbackParams::new( - MechanismType::AES_CMAC, - &data_params, - Some(b"some_initialization_vector"), - None, - ); + let iv = b"sixteen bytes iv"; + let params = KbkdfFeedbackParams::new(MechanismType::AES_CMAC, &data_params, Some(iv), None); // Derive key let derived_key_feedback_iv = session.derive_key( @@ -2492,9 +2594,9 @@ fn kbkdf_double_pipeline_mode() -> TestResult { // Some variables we will use throughout let dkm_length_format = KbkdfDkmLengthFormat::new( - KbkdfDkmLengthMethod::SumOfKeys, + KbkdfDkmLengthMethod::SumOfSegments, Endianness::Big, - NonZeroUsize::new(16).unwrap(), + NonZeroUsize::new(32).unwrap(), ); // Instantiate KBKDF in feedback-mode without additional keys @@ -2601,9 +2703,9 @@ fn kbkdf_additional_keys_counter_mode() -> TestResult { // Some variables we will use throughout let counter_format = KbkdfCounterFormat::new(Endianness::Big, NonZeroUsize::new(16).unwrap()); let dkm_length_format = KbkdfDkmLengthFormat::new( - KbkdfDkmLengthMethod::SumOfKeys, + KbkdfDkmLengthMethod::SumOfSegments, Endianness::Big, - NonZeroUsize::new(16).unwrap(), + NonZeroUsize::new(32).unwrap(), ); // Instantiate KBKDF in counter-mode without additional keys @@ -2759,7 +2861,7 @@ fn kbkdf_additional_keys_feedback_mode() -> TestResult { let dkm_length_format = KbkdfDkmLengthFormat::new( KbkdfDkmLengthMethod::SumOfKeys, Endianness::Big, - NonZeroUsize::new(16).unwrap(), + NonZeroUsize::new(32).unwrap(), ); let mut derived_keys = vec![]; @@ -2808,10 +2910,11 @@ fn kbkdf_additional_keys_feedback_mode() -> TestResult { .iter() .map(|template| DerivedKey::new(template)) .collect::>(); + let iv = b"sixteen bytes iv"; let params = KbkdfFeedbackParams::new( MechanismType::AES_CMAC, &data_params, - Some(b"some_initialization_vector"), + Some(iv), Some(&mut additional_derived_keys), ); @@ -2941,9 +3044,9 @@ fn kbkdf_additional_keys_double_pipeline_mode() -> TestResult { // Some variables we will use throughout let dkm_length_format = KbkdfDkmLengthFormat::new( - KbkdfDkmLengthMethod::SumOfKeys, + KbkdfDkmLengthMethod::SumOfSegments, Endianness::Big, - NonZeroUsize::new(16).unwrap(), + NonZeroUsize::new(32).unwrap(), ); // Instantiate KBKDF in feedback-mode without additional keys @@ -3075,9 +3178,9 @@ fn kbkdf_invalid_data_params_counter_mode() -> TestResult { // Some variables we will use throughout let counter_format = KbkdfCounterFormat::new(Endianness::Big, NonZeroUsize::new(16).unwrap()); let dkm_length_format = KbkdfDkmLengthFormat::new( - KbkdfDkmLengthMethod::SumOfKeys, + KbkdfDkmLengthMethod::SumOfSegments, Endianness::Big, - NonZeroUsize::new(16).unwrap(), + NonZeroUsize::new(32).unwrap(), ); /* MISSING ITERATION VARIABLE */ @@ -3224,9 +3327,9 @@ fn kbkdf_invalid_data_params_feedback_mode() -> TestResult { // Some variables we will use throughout let counter_format = KbkdfCounterFormat::new(Endianness::Big, NonZeroUsize::new(16).unwrap()); let dkm_length_format = KbkdfDkmLengthFormat::new( - KbkdfDkmLengthMethod::SumOfKeys, + KbkdfDkmLengthMethod::SumOfSegments, Endianness::Big, - NonZeroUsize::new(16).unwrap(), + NonZeroUsize::new(32).unwrap(), ); /* MISSING ITERATION VARIABLE */ @@ -3347,9 +3450,9 @@ fn kbkdf_invalid_data_params_double_pipeline_mode() -> TestResult { // Some variables we will use throughout let counter_format = KbkdfCounterFormat::new(Endianness::Big, NonZeroUsize::new(16).unwrap()); let dkm_length_format = KbkdfDkmLengthFormat::new( - KbkdfDkmLengthMethod::SumOfKeys, + KbkdfDkmLengthMethod::SumOfSegments, Endianness::Big, - NonZeroUsize::new(16).unwrap(), + NonZeroUsize::new(32).unwrap(), ); /* MISSING ITERATION VARIABLE */ @@ -3757,7 +3860,6 @@ fn aes_cmac_verify_impl(key: [u8; 16], message: &[u8], expected_mac: [u8; 16]) - Ok(()) } -/// AES-CMAC test vectors from RFC 4493 #[test] #[serial] fn unique_id() -> TestResult { @@ -3822,13 +3924,89 @@ fn unique_id() -> TestResult { )) )); } else { + assert!(matches!( + res, + Err(Error::Pkcs11(_, Function::SetAttributeValue)) + )); + } + + session.destroy_object(key)?; + + Ok(()) +} + +#[test] +#[serial] +fn validation() -> TestResult { + let (pkcs11, slot) = init_pins(); + let session = pkcs11.open_rw_session(slot)?; + session.login(UserType::User, Some(&AuthPin::new(USER_PIN.into())))?; + + let key: [u8; 16] = [ + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, + 0x3c, + ]; + + // Can not create object with ObjectValidationFlags + let key_template = vec![ + Attribute::Class(ObjectClass::SECRET_KEY), + Attribute::KeyType(KeyType::AES), + Attribute::Token(true), + Attribute::Sensitive(true), + Attribute::Private(true), + Attribute::Value(key.into()), + Attribute::ObjectValidationFlags(0x03.into()), + ]; + let res = session.create_object(&key_template); + assert!(res.is_err()); + assert!(matches!( + res, + Err(Error::Pkcs11( + RvError::AttributeTypeInvalid, + Function::CreateObject + )) + )); + + let generate_template = vec![ + Attribute::Token(true), + Attribute::ValueLen(32.into()), + Attribute::Encrypt(true), + ]; + + // generate a secret key + let key = session.generate_key(&Mechanism::AesKeyGen, &generate_template)?; + + // we can get the ObjectValidationFlags attribute + let attrs = session.get_attributes(key, &[AttributeType::ObjectValidationFlags])?; + if is_fips(&session) { + // Kryoptic supports the ObjectValidationFlag only if it is built as a FIPS provider + if let Attribute::ObjectValidationFlags(flag) = attrs.first().unwrap() { + assert_eq!(flag, &Ulong::new(1)); + } else { + panic!("The ObjectValidationFlags attribute was expected to be present.") + }; + } else { + assert_eq!(attrs.len(), 0); + } + + // we can not set the ObjectValidationFlags attribute + let update_template = vec![Attribute::ObjectValidationFlags(0x03.into())]; + let res = session.update_attributes(key, &update_template); + assert!(res.is_err()); + if is_softhsm() { + // SoftHSM does not support this attribute at all assert!(matches!( res, Err(Error::Pkcs11( - RvError::ActionProhibited, + RvError::AttributeTypeInvalid, Function::SetAttributeValue )) )); + } else { + assert!(matches!( + res, + Err(Error::Pkcs11(_, Function::SetAttributeValue)) + )); } session.destroy_object(key)?; diff --git a/cryptoki/tests/common/mod.rs b/cryptoki/tests/common/mod.rs index 41d200ac..e7968542 100644 --- a/cryptoki/tests/common/mod.rs +++ b/cryptoki/tests/common/mod.rs @@ -1,15 +1,16 @@ // Copyright 2021 Contributors to the Parsec project. // SPDX-License-Identifier: Apache-2.0 use cryptoki::context::{CInitializeArgs, Pkcs11}; -use cryptoki::session::UserType; +use cryptoki::object::{Attribute, ObjectClass}; +use cryptoki::session::{Session, UserType}; use cryptoki::slot::Slot; use cryptoki::types::AuthPin; use std::env; // The default user pin -pub static USER_PIN: &str = "fedcba"; +pub static USER_PIN: &str = "fedcba123456"; // The default SO pin -pub static SO_PIN: &str = "abcdef"; +pub static SO_PIN: &str = "abcdef654321"; fn get_pkcs11_path() -> String { env::var("TEST_PKCS11_MODULE") @@ -26,6 +27,16 @@ pub fn is_kryoptic() -> bool { get_pkcs11_path().contains("kryoptic") } +#[allow(dead_code)] +pub fn is_fips(session: &Session) -> bool { + let template = vec![Attribute::Class(ObjectClass::VALIDATION)]; + + match session.find_objects(&template) { + Ok(l) => !l.is_empty(), + Err(_) => false, + } +} + pub fn get_pkcs11() -> Pkcs11 { Pkcs11::new(get_pkcs11_path()).unwrap() }