├── .gitignore ├── CMakeLists.txt ├── CODE_OF_CONDUCT.md ├── EvpTestRecipes ├── 1.1.1 │ ├── evpcase.txt │ ├── evpccmcavs.txt │ ├── evpciph.txt │ ├── evpdigest.txt │ ├── evpkdf.txt │ ├── evpmac.txt │ ├── evppkey.txt │ └── evppkey_ecc.txt ├── 3.0 │ ├── evpciph_aes_ccm_cavs.txt │ ├── evpciph_aes_engine.txt │ ├── evpciph_aes_provider.txt │ ├── evpkdf_hkdf.txt │ ├── evpkdf_kbkdf_counter.txt │ ├── evpkdf_kbkdf_kmac.txt │ ├── evpkdf_pbkdf2.txt │ ├── evpkdf_srtpkdf.txt │ ├── evpkdf_ss.txt │ ├── evpkdf_ssh.txt │ ├── evpkdf_tls11_prf.txt │ ├── evpkdf_tls12_prf.txt │ ├── evpmac_common.txt │ ├── evpmac_engine.txt │ ├── evpmd_sha.txt │ ├── evppkey_dh.txt │ ├── evppkey_ecdh.txt │ ├── evppkey_ecdsa.txt │ ├── evppkey_ecdsa_named.txt │ ├── evppkey_ecx.txt │ ├── evppkey_ffdhe.txt │ ├── evppkey_kdf_hkdf.txt │ ├── evppkey_kdf_tls1_prf.txt │ ├── evppkey_rsa.txt │ ├── evppkey_rsa_common.txt │ ├── evppkey_rsa_engine.txt │ └── evppkey_rsa_provider.txt └── README.md ├── LICENSE ├── NOTICE ├── README.md ├── SECURITY.md ├── ScosslCommon ├── CMakeLists.txt ├── inc │ ├── scossl_aes_aead.h │ ├── scossl_dh.h │ ├── scossl_ecc.h │ ├── scossl_helpers.h │ ├── scossl_hkdf.h │ ├── scossl_mac.h │ ├── scossl_rsa.h │ ├── scossl_sshkdf.h │ └── scossl_tls1prf.h └── src │ ├── scossl_aes_aead.c │ ├── scossl_dh.c │ ├── scossl_ecc.c │ ├── scossl_helpers.c │ ├── scossl_hkdf.c │ ├── scossl_mac.c │ ├── scossl_rsa.c │ ├── scossl_sshkdf.c │ └── scossl_tls1prf.c ├── SslPlay ├── CMakeLists.txt └── SslPlay.cpp ├── SymCryptEngine ├── README.md ├── dynamic │ ├── CMakeLists.txt │ └── OpenSSLConfig.conf ├── inc │ └── e_scossl.h ├── src │ ├── e_scossl.c │ ├── e_scossl_ciphers.c │ ├── e_scossl_ciphers.h │ ├── e_scossl_dh.c │ ├── e_scossl_dh.h │ ├── e_scossl_digests.c │ ├── e_scossl_digests.h │ ├── e_scossl_dsa.c │ ├── e_scossl_dsa.h │ ├── e_scossl_ecc.c │ ├── e_scossl_ecc.h │ ├── e_scossl_hkdf.c │ ├── e_scossl_hkdf.h │ ├── e_scossl_hmac.c │ ├── e_scossl_hmac.h │ ├── e_scossl_pkey_meths.c │ ├── e_scossl_pkey_meths.h │ ├── e_scossl_rand.c │ ├── e_scossl_rand.h │ ├── e_scossl_rsa.c │ ├── e_scossl_rsa.h │ ├── e_scossl_rsapss.c │ ├── e_scossl_rsapss.h │ ├── e_scossl_sshkdf.c │ ├── e_scossl_sshkdf.h │ ├── e_scossl_tls1prf.c │ └── e_scossl_tls1prf.h └── static │ └── CMakeLists.txt ├── SymCryptProvider ├── CMakeLists.txt ├── README.md ├── inc │ ├── p_scossl_base.h.in │ └── scossl_provider.h ├── src │ ├── asymcipher │ │ └── p_scossl_rsa_cipher.c │ ├── ciphers │ │ ├── p_scossl_aes.c │ │ ├── p_scossl_aes.h │ │ ├── p_scossl_aes_aead.c │ │ └── p_scossl_aes_xts.c │ ├── decoder │ │ ├── p_scossl_decode_common.c │ │ ├── p_scossl_decode_common.h │ │ └── p_scossl_decode_mlkem.c │ ├── digests │ │ ├── p_scossl_cshake.c │ │ ├── p_scossl_digest_common.c │ │ ├── p_scossl_digest_common.h │ │ ├── p_scossl_digest_generic.c │ │ └── p_scossl_shake.c │ ├── encoder │ │ ├── p_scossl_encode_common.c │ │ ├── p_scossl_encode_common.h │ │ └── p_scossl_encode_mlkem.c │ ├── kdf │ │ ├── p_scossl_hkdf.c │ │ ├── p_scossl_hkdf.h │ │ ├── p_scossl_kbkdf.c │ │ ├── p_scossl_pbkdf2.c │ │ ├── p_scossl_srtpkdf.c │ │ ├── p_scossl_sshkdf.c │ │ ├── p_scossl_sskdf.c │ │ ├── p_scossl_tls1prf.c │ │ └── p_scossl_tls1prf.h │ ├── kem │ │ ├── p_scossl_mlkem.c │ │ └── p_scossl_mlkem.h │ ├── keyexch │ │ ├── p_scossl_dh.c │ │ ├── p_scossl_dh.h │ │ ├── p_scossl_ecdh.c │ │ ├── p_scossl_ecdh.h │ │ └── p_scossl_kdf_keyexch.c │ ├── keymgmt │ │ ├── p_scossl_dh_keymgmt.c │ │ ├── p_scossl_ecc_keymgmt.c │ │ ├── p_scossl_ecc_keymgmt.h │ │ ├── p_scossl_kdf_keymgmt.c │ │ ├── p_scossl_mlkem_keymgmt.c │ │ ├── p_scossl_mlkem_keymgmt.h │ │ └── p_scossl_rsa_keymgmt.c │ ├── mac │ │ ├── p_scossl_cmac.c │ │ ├── p_scossl_hmac.c │ │ ├── p_scossl_kmac.c │ │ └── p_scossl_kmac.h │ ├── p_scossl_base.c │ ├── p_scossl_bio.c │ ├── p_scossl_bio.h │ ├── p_scossl_ecc.c │ ├── p_scossl_ecc.h │ ├── p_scossl_keysinuse.c │ ├── p_scossl_keysinuse.h │ ├── p_scossl_names.h │ ├── p_scossl_rand.c │ ├── p_scossl_rsa.c │ ├── p_scossl_rsa.h │ └── signature │ │ ├── p_scossl_ecdsa_signature.c │ │ └── p_scossl_rsa_signature.c └── symcrypt_prov.cnf └── cmake-toolchain ├── LinuxUserMode-AMD64.cmake ├── LinuxUserMode-ARM.cmake └── LinuxUserMode-ARM64.cmake /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13.0) 2 | 3 | project(SymCrypt-OpenSSL 4 | VERSION 1.10.0 5 | DESCRIPTION "The SymCrypt engine and provider for OpenSSL (SCOSSL)" 6 | HOMEPAGE_URL "https://github.com/microsoft/SymCrypt-OpenSSL") 7 | 8 | set(SYMCRYPT_MINIMUM_MAJOR "103") 9 | set(SYMCRYPT_MINIMUM_MINOR "6") 10 | 11 | find_package(OpenSSL REQUIRED) 12 | 13 | if (SYMCRYPT_ROOT_DIR) 14 | include_directories(${SYMCRYPT_ROOT_DIR}/inc) 15 | else() 16 | find_package(PkgConfig) 17 | if (PKG_CONFIG_FOUND) 18 | pkg_check_modules(SYMCRYPT REQUIRED symcrypt>=${SYMCRYPT_MINIMUM_MAJOR}.${SYMCRYPT_MINIMUM_MINOR}) 19 | message(STATUS "SymCrypt Includes: ${SYMCRYPT_INCLUDE_DIRS}") 20 | include_directories(${SYMCRYPT_INCLUDE_DIRS}) 21 | else() 22 | message(FATAL_ERROR "Provide symcrypt pkg-config or set SYMCRYPT_ROOT_DIR variable") 23 | endif() 24 | endif (SYMCRYPT_ROOT_DIR) 25 | 26 | # In Sanitize version, enable sanitizers 27 | if (CMAKE_BUILD_TYPE MATCHES Sanitize) 28 | add_compile_options(-fsanitize=address) 29 | add_compile_options(-fsanitize=leak) 30 | add_compile_options(-fsanitize=undefined) 31 | add_compile_options(-fno-sanitize-recover=all) 32 | add_link_options(-fsanitize=address) 33 | add_link_options(-fsanitize=leak) 34 | add_link_options(-fsanitize=undefined) 35 | add_link_options(-fno-sanitize-recover=all) 36 | endif() 37 | 38 | if (CMAKE_BUILD_TYPE MATCHES Release|RelWithDebInfo) 39 | message("Release mode") 40 | else() 41 | message("Debug mode") 42 | add_compile_options(-DDBG=1) 43 | endif() 44 | 45 | add_subdirectory (ScosslCommon) 46 | add_subdirectory (SymCryptEngine/static) 47 | add_subdirectory (SymCryptEngine/dynamic) 48 | add_subdirectory (SslPlay) 49 | 50 | if (${OPENSSL_VERSION} VERSION_GREATER_EQUAL 3) 51 | add_subdirectory (SymCryptProvider) 52 | endif() 53 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Microsoft Open Source Code of Conduct 2 | 3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 4 | 5 | Resources: 6 | 7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) 8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) 9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns 10 | -------------------------------------------------------------------------------- /EvpTestRecipes/1.1.1/evpcase.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. 3 | # 4 | # Licensed under the OpenSSL license (the "License"). You may not use 5 | # this file except in compliance with the License. You can obtain a copy 6 | # in the file LICENSE in the source distribution or at 7 | # https://www.openssl.org/source/license.html 8 | 9 | # Tests start with one of these keywords 10 | # Cipher Decrypt Derive Digest Encoding KDF MAC PBE 11 | # PrivPubKeyPair Sign Verify VerifyRecover 12 | # and continue until a blank line. Lines starting with a pound sign, 13 | # like this prolog, are ignored. 14 | 15 | # These tests exercise the case insensitive handling of object names. 16 | # They are contrived 17 | 18 | Title = Case insensitive AES tests 19 | 20 | Cipher = Aes-128-eCb 21 | Key = 2B7E151628AED2A6ABF7158809CF4F3C 22 | Plaintext = 6BC1BEE22E409F96E93D7E117393172A 23 | Ciphertext = 3AD77BB40D7A3660A89ECAF32466EF97 24 | 25 | Cipher = AeS-128-cbC 26 | Key = 2B7E151628AED2A6ABF7158809CF4F3C 27 | IV = 73BED6B8E3C1743B7116E69E22229516 28 | Plaintext = F69F2445DF4F9B17AD2B417BE66C3710 29 | Ciphertext = 3FF1CAA1681FAC09120ECA307586E1A7 30 | 31 | Cipher = aES-128-CTR 32 | Key = AE6852F8121067CC4BF7A5765577F39E 33 | IV = 00000030000000000000000000000001 34 | Operation = ENCRYPT 35 | Plaintext = 53696E676C6520626C6F636B206D7367 36 | Ciphertext = E4095D4FB7A7B3792D6175A3261311B8 37 | 38 | Cipher = AES-128-GcM 39 | Key = 00000000000000000000000000000000 40 | IV = 000000000000000000000000 41 | AAD = 42 | Tag = ab6e47d42cec13bdf53a67b21257bddf 43 | Plaintext = 00000000000000000000000000000000 44 | Ciphertext = 0388dace60b6a392f328c2b971b2fe78 45 | 46 | Title = Case insensitive digest tests 47 | 48 | Digest = Sha3-256 49 | Input = "" 50 | Output = A7FFC6F8BF1ED76651C14756A061D662F580FF4DE43B49FA82D80A4B80F8434A 51 | 52 | Digest = shA512 53 | Input = "abc" 54 | Output = ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f 55 | -------------------------------------------------------------------------------- /EvpTestRecipes/3.0/evpkdf_kbkdf_counter.txt: -------------------------------------------------------------------------------- 1 | 2 | Title = KBKDF tests 3 | 4 | KDF = KBKDF 5 | Ctrl.mode = mode:COUNTER 6 | Ctrl.digest = digest:SHA1 7 | Ctrl.mac = mac:HMAC 8 | Ctrl.use-l = use-l:1 9 | Ctrl.use-separator = use-separator:1 10 | Ctrl.salt = salt:Label 11 | Ctrl.hexkey = hexkey:0001020304050607 12 | Ctrl.hexinfo = hexinfo:101112131415161718191a1b1c1d1e1f 13 | Output = cf4bfe4f85a10bad 14 | 15 | KDF = KBKDF 16 | Ctrl.mode = mode:COUNTER 17 | Ctrl.digest = digest:SHA224 18 | Ctrl.mac = mac:HMAC 19 | Ctrl.use-l = use-l:1 20 | Ctrl.use-separator = use-separator:1 21 | Ctrl.salt = salt:Label 22 | Ctrl.hexkey = hexkey:0001020304050607 23 | Ctrl.hexinfo = hexinfo:101112131415161718191a1b1c1d1e1f 24 | Output = 6ba2131f742df49b 25 | 26 | KDF = KBKDF 27 | Ctrl.mode = mode:COUNTER 28 | Ctrl.digest = digest:SHA256 29 | Ctrl.mac = mac:HMAC 30 | Ctrl.use-l = use-l:1 31 | Ctrl.use-separator = use-separator:1 32 | Ctrl.salt = salt:Label 33 | Ctrl.hexkey = hexkey:0001020304050607 34 | Ctrl.hexinfo = hexinfo:101112131415161718191a1b1c1d1e1f 35 | Output = 00264bbb14974054 36 | 37 | KDF = KBKDF 38 | Ctrl.mode = mode:COUNTER 39 | Ctrl.digest = digest:SHA384 40 | Ctrl.mac = mac:HMAC 41 | Ctrl.use-l = use-l:1 42 | Ctrl.use-separator = use-separator:1 43 | Ctrl.salt = salt:Label 44 | Ctrl.hexkey = hexkey:0001020304050607 45 | Ctrl.hexinfo = hexinfo:101112131415161718191a1b1c1d1e1f 46 | Output = c7102787d896bc89 47 | 48 | KDF = KBKDF 49 | Ctrl.mode = mode:COUNTER 50 | Ctrl.digest = digest:SHA512 51 | Ctrl.mac = mac:HMAC 52 | Ctrl.use-l = use-l:1 53 | Ctrl.use-separator = use-separator:1 54 | Ctrl.salt = salt:Label 55 | Ctrl.hexkey = hexkey:0001020304050607 56 | Ctrl.hexinfo = hexinfo:101112131415161718191a1b1c1d1e1f 57 | Output = db3a18d96c4ad41e 58 | 59 | KDF = KBKDF 60 | Ctrl.mode = mode:COUNTER 61 | Ctrl.digest = digest:SHA512-224 62 | Ctrl.mac = mac:HMAC 63 | Ctrl.use-l = use-l:1 64 | Ctrl.use-separator = use-separator:1 65 | Ctrl.salt = salt:Label 66 | Ctrl.hexkey = hexkey:0001020304050607 67 | Ctrl.hexinfo = hexinfo:101112131415161718191a1b1c1d1e1f 68 | Output = 433fb6029801ccf5 69 | 70 | KDF = KBKDF 71 | Ctrl.mode = mode:COUNTER 72 | Ctrl.digest = digest:SHA512-256 73 | Ctrl.mac = mac:HMAC 74 | Ctrl.use-l = use-l:1 75 | Ctrl.use-separator = use-separator:1 76 | Ctrl.salt = salt:Label 77 | Ctrl.hexkey = hexkey:0001020304050607 78 | Ctrl.hexinfo = hexinfo:101112131415161718191a1b1c1d1e1f 79 | Output = 31117cf3b4622835 80 | 81 | KDF = KBKDF 82 | Ctrl.mode = mode:COUNTER 83 | Ctrl.digest = digest:SHA3-224 84 | Ctrl.mac = mac:HMAC 85 | Ctrl.use-l = use-l:1 86 | Ctrl.use-separator = use-separator:1 87 | Ctrl.salt = salt:Label 88 | Ctrl.hexkey = hexkey:0001020304050607 89 | Ctrl.hexinfo = hexinfo:101112131415161718191a1b1c1d1e1f 90 | Output = 843c04b2542d8ca4 91 | 92 | 93 | KDF = KBKDF 94 | Ctrl.mode = mode:COUNTER 95 | Ctrl.digest = digest:SHA3-256 96 | Ctrl.mac = mac:HMAC 97 | Ctrl.use-l = use-l:1 98 | Ctrl.use-separator = use-separator:1 99 | Ctrl.salt = salt:Label 100 | Ctrl.hexkey = hexkey:0001020304050607 101 | Ctrl.hexinfo = hexinfo:101112131415161718191a1b1c1d1e1f 102 | Output = d4c72c668a1de0b9 103 | 104 | 105 | KDF = KBKDF 106 | Ctrl.mode = mode:COUNTER 107 | Ctrl.digest = digest:SHA3-384 108 | Ctrl.mac = mac:HMAC 109 | Ctrl.use-l = use-l:1 110 | Ctrl.use-separator = use-separator:1 111 | Ctrl.salt = salt:Label 112 | Ctrl.hexkey = hexkey:0001020304050607 113 | Ctrl.hexinfo = hexinfo:101112131415161718191a1b1c1d1e1f 114 | Output = f6392bd50ae4361b 115 | 116 | KDF = KBKDF 117 | Ctrl.mode = mode:COUNTER 118 | Ctrl.digest = digest:SHA3-512 119 | Ctrl.mac = mac:HMAC 120 | Ctrl.use-l = use-l:1 121 | Ctrl.use-separator = use-separator:1 122 | Ctrl.salt = salt:Label 123 | Ctrl.hexkey = hexkey:0001020304050607 124 | Ctrl.hexinfo = hexinfo:101112131415161718191a1b1c1d1e1f 125 | Output = 5a0d0630a248121f 126 | -------------------------------------------------------------------------------- /EvpTestRecipes/3.0/evpkdf_pbkdf2.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved. 3 | # 4 | # Licensed under the Apache License 2.0 (the "License"). You may not use 5 | # this file except in compliance with the License. You can obtain a copy 6 | # in the file LICENSE in the source distribution or at 7 | # https://www.openssl.org/source/license.html 8 | 9 | # Tests start with one of these keywords 10 | # Cipher Decrypt Derive Digest Encoding KDF MAC PBE 11 | # PrivPubKeyPair Sign Verify VerifyRecover 12 | # and continue until a blank line. Lines starting with a pound sign are ignored. 13 | 14 | Title = PBKDF2 tests 15 | 16 | KDF = PBKDF2 17 | Ctrl.pkcs5 = pkcs5:1 18 | Ctrl.pass = pass:password 19 | Ctrl.salt = salt:salt 20 | Ctrl.iter = iter:1 21 | Ctrl.digest = digest:sha1 22 | Output = 0c60c80f961f0e71f3a9b524af6012062fe037a6 23 | 24 | KDF = PBKDF2 25 | Ctrl.pkcs5 = pkcs5:1 26 | Ctrl.pass = pass:password 27 | Ctrl.salt = salt:salt 28 | Ctrl.iter = iter:1 29 | Ctrl.digest = digest:sha256 30 | Output = 120fb6cffcf8b32c43e7225256c4f837a86548c92ccc35480805987cb70be17b 31 | 32 | KDF = PBKDF2 33 | Ctrl.pkcs5 = pkcs5:1 34 | Ctrl.pass = pass:password 35 | Ctrl.salt = salt:salt 36 | Ctrl.iter = iter:1 37 | Ctrl.digest = digest:sha512 38 | Output = 867f70cf1ade02cff3752599a3a53dc4af34c7a669815ae5d513554e1c8cf252c02d470a285a0501bad999bfe943c08f050235d7d68b1da55e63f73b60a57fce 39 | 40 | KDF = PBKDF2 41 | Ctrl.pkcs5 = pkcs5:1 42 | Ctrl.pass = pass:password 43 | Ctrl.salt = salt:salt 44 | Ctrl.iter = iter:2 45 | Ctrl.digest = digest:sha1 46 | Output = ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957 47 | 48 | KDF = PBKDF2 49 | Ctrl.pkcs5 = pkcs5:1 50 | Ctrl.pass = pass:password 51 | Ctrl.salt = salt:salt 52 | Ctrl.iter = iter:2 53 | Ctrl.digest = digest:sha256 54 | Output = ae4d0c95af6b46d32d0adff928f06dd02a303f8ef3c251dfd6e2d85a95474c43 55 | 56 | KDF = PBKDF2 57 | Ctrl.pkcs5 = pkcs5:1 58 | Ctrl.pass = pass:password 59 | Ctrl.salt = salt:salt 60 | Ctrl.iter = iter:2 61 | Ctrl.digest = digest:sha512 62 | Output = e1d9c16aa681708a45f5c7c4e215ceb66e011a2e9f0040713f18aefdb866d53cf76cab2868a39b9f7840edce4fef5a82be67335c77a6068e04112754f27ccf4e 63 | 64 | KDF = PBKDF2 65 | Ctrl.pkcs5 = pkcs5:1 66 | Ctrl.pass = pass:password 67 | Ctrl.salt = salt:salt 68 | Ctrl.iter = iter:4096 69 | Ctrl.digest = digest:sha1 70 | Output = 4b007901b765489abead49d926f721d065a429c1 71 | 72 | KDF = PBKDF2 73 | Ctrl.pkcs5 = pkcs5:1 74 | Ctrl.pass = pass:password 75 | Ctrl.salt = salt:salt 76 | Ctrl.iter = iter:4096 77 | Ctrl.digest = digest:sha256 78 | Output = c5e478d59288c841aa530db6845c4c8d962893a001ce4e11a4963873aa98134a 79 | 80 | KDF = PBKDF2 81 | Ctrl.pkcs5 = pkcs5:1 82 | Ctrl.pass = pass:password 83 | Ctrl.salt = salt:salt 84 | Ctrl.iter = iter:4096 85 | Ctrl.digest = digest:sha512 86 | Output = d197b1b33db0143e018b12f3d1d1479e6cdebdcc97c5c0f87f6902e072f457b5143f30602641b3d55cd335988cb36b84376060ecd532e039b742a239434af2d5 87 | 88 | KDF = PBKDF2 89 | Ctrl.pass = pass:passwordPASSWORDpassword 90 | Ctrl.salt = salt:saltSALTsaltSALTsaltSALTsaltSALTsalt 91 | Ctrl.iter = iter:4096 92 | Ctrl.digest = digest:sha1 93 | Output = 3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038 94 | 95 | KDF = PBKDF2 96 | Ctrl.pass = pass:passwordPASSWORDpassword 97 | Ctrl.salt = salt:saltSALTsaltSALTsaltSALTsaltSALTsalt 98 | Ctrl.iter = iter:4096 99 | Ctrl.digest = digest:sha256 100 | Output = 348c89dbcbd32b2f32d814b8116e84cf2b17347ebc1800181c4e2a1fb8dd53e1c635518c7dac47e9 101 | 102 | KDF = PBKDF2 103 | Ctrl.pass = pass:passwordPASSWORDpassword 104 | Ctrl.salt = salt:saltSALTsaltSALTsaltSALTsaltSALTsalt 105 | Ctrl.iter = iter:4096 106 | Ctrl.digest = digest:sha512 107 | Output = 8c0511f4c6e597c6ac6315d8f0362e225f3c501495ba23b868c005174dc4ee71115b59f9e60cd9532fa33e0f75aefe30225c583a186cd82bd4daea9724a3d3b8 108 | 109 | KDF = PBKDF2 110 | Ctrl.pkcs5 = pkcs5:1 111 | Ctrl.hexpass = hexpass:7061737300776f7264 112 | Ctrl.hexsalt = hexsalt:7361006c74 113 | Ctrl.iter = iter:4096 114 | Ctrl.digest = digest:sha1 115 | Output = 56fa6aa75548099dcc37d7f03425e0c3 116 | 117 | KDF = PBKDF2 118 | Ctrl.pkcs5 = pkcs5:1 119 | Ctrl.hexpass = hexpass:7061737300776f7264 120 | Ctrl.hexsalt = hexsalt:7361006c74 121 | Ctrl.iter = iter:4096 122 | Ctrl.digest = digest:sha256 123 | Output = 89b69d0516f829893c696226650a8687 124 | 125 | KDF = PBKDF2 126 | Ctrl.pkcs5 = pkcs5:1 127 | Ctrl.hexpass = hexpass:7061737300776f7264 128 | Ctrl.hexsalt = hexsalt:7361006c74 129 | Ctrl.iter = iter:4096 130 | Ctrl.digest = digest:sha512 131 | Output = 9d9e9c4cd21fe4be24d5b8244c759665 132 | 133 | Title = PBKDF2 tests for empty inputs 134 | 135 | KDF = PBKDF2 136 | Ctrl.pkcs5 = pkcs5:1 137 | Ctrl.pass = pass: 138 | Ctrl.salt = salt:salt 139 | Ctrl.iter = iter:1 140 | Ctrl.digest = digest:sha1 141 | Output = a33dddc30478185515311f8752895d36ea4363a2 142 | 143 | KDF = PBKDF2 144 | Ctrl.pkcs5 = pkcs5:1 145 | Ctrl.pass = pass: 146 | Ctrl.salt = salt:salt 147 | Ctrl.iter = iter:1 148 | Ctrl.digest = digest:sha256 149 | Output = f135c27993baf98773c5cdb40a5706ce6a345cde 150 | 151 | KDF = PBKDF2 152 | Ctrl.pkcs5 = pkcs5:1 153 | Ctrl.pass = pass: 154 | Ctrl.salt = salt:salt 155 | Ctrl.iter = iter:1 156 | Ctrl.digest = digest:sha512 157 | Output = 00ef42cdbfc98d29db20976608e455567fdddf14 158 | -------------------------------------------------------------------------------- /EvpTestRecipes/3.0/evpkdf_tls11_prf.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved. 3 | # 4 | # Licensed under the Apache License 2.0 (the "License"). You may not use 5 | # this file except in compliance with the License. You can obtain a copy 6 | # in the file LICENSE in the source distribution or at 7 | # https://www.openssl.org/source/license.html 8 | 9 | # Tests start with one of these keywords 10 | # Cipher Decrypt Derive Digest Encoding KDF MAC PBE 11 | # PrivPubKeyPair Sign Verify VerifyRecover 12 | # and continue until a blank line. Lines starting with a pound sign are ignored. 13 | 14 | Title = TLS1 PRF tests (from NIST test vectors) 15 | 16 | KDF = TLS1-PRF 17 | Ctrl.digest = digest:MD5-SHA1 18 | Ctrl.Secret = hexsecret:bded7fa5c1699c010be23dd06ada3a48349f21e5f86263d512c0c5cc379f0e780ec55d9844b2f1db02a96453513568d0 19 | Ctrl.label = seed:master secret 20 | Ctrl.client_random = hexseed:e5acaf549cd25c22d964c0d930fa4b5261d2507fad84c33715b7b9a864020693 21 | Ctrl.server_random = hexseed:135e4d557fdf3aa6406d82975d5c606a9734c9334b42136e96990fbd5358cdb2 22 | Output = 2f6962dfbc744c4b2138bb6b3d33054c5ecc14f24851d9896395a44ab3964efc2090c5bf51a0891209f46c1e1e998f62 23 | 24 | KDF = TLS1-PRF 25 | Ctrl.digest = digest:MD5-SHA1 26 | Ctrl.Secret = hexsecret:2f6962dfbc744c4b2138bb6b3d33054c5ecc14f24851d9896395a44ab3964efc2090c5bf51a0891209f46c1e1e998f62 27 | Ctrl.label = seed:key expansion 28 | Ctrl.server_random = hexseed:67267e650eb32444119d222a368c191af3082888dc35afe8368e638c828874be 29 | Ctrl.client_random = hexseed:d58a7b1cd4fedaa232159df652ce188f9d997e061b9bf48e83b62990440931f6 30 | Output = 3088825988e77fce68d19f756e18e43eb7fe672433504feaf99b3c503d9091b164f166db301d70c9fc0870b4a94563907bee1a61fb786cb717576890bcc51cb9ead97e01d0a2fea99c953377b195205ff07b369589178796edc963fd80fdbe518a2fc1c35c18ae8d 31 | 32 | # Missing secret. 33 | KDF = TLS1-PRF 34 | Ctrl.digest = digest:MD5-SHA1 35 | Ctrl.Seed = hexseed:02 36 | Output = 03 37 | Result = KDF_DERIVE_ERROR 38 | -------------------------------------------------------------------------------- /EvpTestRecipes/3.0/evpkdf_tls12_prf.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved. 3 | # 4 | # Licensed under the Apache License 2.0 (the "License"). You may not use 5 | # this file except in compliance with the License. You can obtain a copy 6 | # in the file LICENSE in the source distribution or at 7 | # https://www.openssl.org/source/license.html 8 | 9 | # Tests start with one of these keywords 10 | # Cipher Decrypt Derive Digest Encoding KDF MAC PBE 11 | # PrivPubKeyPair Sign Verify VerifyRecover 12 | # and continue until a blank line. Lines starting with a pound sign are ignored. 13 | 14 | Title = TLS12 PRF tests (from NIST test vectors) 15 | 16 | KDF = TLS1-PRF 17 | Ctrl.digest = digest:SHA256 18 | Ctrl.Secret = hexsecret:f8938ecc9edebc5030c0c6a441e213cd24e6f770a50dda07876f8d55da062bcadb386b411fd4fe4313a604fce6c17fbc 19 | Ctrl.label = seed:master secret 20 | Ctrl.client_random = hexseed:36c129d01a3200894b9179faac589d9835d58775f9b5ea3587cb8fd0364cae8c 21 | Ctrl.server_random = hexseed:f6c9575ed7ddd73e1f7d16eca115415812a43c2b747daaaae043abfb50053fce 22 | Output = 202c88c00f84a17a20027079604787461176455539e705be730890602c289a5001e34eeb3a043e5d52a65e66125188bf 23 | 24 | KDF = TLS1-PRF 25 | Ctrl.digest = digest:SHA256 26 | Ctrl.Secret = hexsecret:202c88c00f84a17a20027079604787461176455539e705be730890602c289a5001e34eeb3a043e5d52a65e66125188bf 27 | Ctrl.label = seed:key expansion 28 | Ctrl.server_random = hexseed:ae6c806f8ad4d80784549dff28a4b58fd837681a51d928c3e30ee5ff14f39868 29 | Ctrl.client_random = hexseed:62e1fd91f23f558a605f28478c58cf72637b89784d959df7e946d3f07bd1b616 30 | Output = d06139889fffac1e3a71865f504aa5d0d2a2e89506c6f2279b670c3e1b74f531016a2530c51a3a0f7e1d6590d0f0566b2f387f8d11fd4f731cdd572d2eae927f6f2f81410b25e6960be68985add6c38445ad9f8c64bf8068bf9a6679485d966f1ad6f68b43495b10a683755ea2b858d70ccac7ec8b053c6bd41ca299d4e51928 31 | 32 | # As above but use long name for KDF 33 | KDF = tls1-prf 34 | Ctrl.digest = digest:SHA256 35 | Ctrl.Secret = hexsecret:202c88c00f84a17a20027079604787461176455539e705be730890602c289a5001e34eeb3a043e5d52a65e66125188bf 36 | Ctrl.label = seed:key expansion 37 | Ctrl.server_random = hexseed:ae6c806f8ad4d80784549dff28a4b58fd837681a51d928c3e30ee5ff14f39868 38 | Ctrl.client_random = hexseed:62e1fd91f23f558a605f28478c58cf72637b89784d959df7e946d3f07bd1b616 39 | Output = d06139889fffac1e3a71865f504aa5d0d2a2e89506c6f2279b670c3e1b74f531016a2530c51a3a0f7e1d6590d0f0566b2f387f8d11fd4f731cdd572d2eae927f6f2f81410b25e6960be68985add6c38445ad9f8c64bf8068bf9a6679485d966f1ad6f68b43495b10a683755ea2b858d70ccac7ec8b053c6bd41ca299d4e51928 40 | 41 | # Missing digest. 42 | KDF = TLS1-PRF 43 | Ctrl.Secret = hexsecret:01 44 | Ctrl.Seed = hexseed:02 45 | Output = 03 46 | Result = KDF_DERIVE_ERROR 47 | -------------------------------------------------------------------------------- /EvpTestRecipes/3.0/evpmac_engine.txt: -------------------------------------------------------------------------------- 1 | Title = HMAC tests (from RFC2104 and others) 2 | 3 | Title = MD5 4 | 5 | Availablein = default 6 | MAC = HMAC 7 | Algorithm = MD5 8 | Key = 0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b 9 | Input = "Hi There" 10 | Output = 9294727a3638bb1c13f48ef8158bfc9d 11 | OutputSize = 16 12 | BlockSize = 64 13 | 14 | Availablein = default 15 | MAC = HMAC 16 | Algorithm = MD5 17 | Key = "Jefe" 18 | Input = "what do ya want for nothing?" 19 | Output = 750c783e6ab0b503eaa86e310a5db738 20 | OutputSize = 16 21 | 22 | Availablein = default 23 | MAC = HMAC 24 | Algorithm = MD5 25 | Key = AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 26 | Input = DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD 27 | Output = 56be34521d144c88dbb8c733f0e8b3f6 28 | BlockSize = 64 29 | -------------------------------------------------------------------------------- /EvpTestRecipes/3.0/evppkey_ecx.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved. 3 | # 4 | # Licensed under the Apache License 2.0 (the "License"). You may not use 5 | # this file except in compliance with the License. You can obtain a copy 6 | # in the file LICENSE in the source distribution or at 7 | # https://www.openssl.org/source/license.html 8 | 9 | # Tests start with one of these keywords 10 | # Cipher Decrypt Derive Digest Encoding KDF MAC PBE 11 | # PrivPubKeyPair Sign Verify VerifyRecover 12 | # and continue until a blank line. Lines starting with a pound sign are ignored. 13 | 14 | 15 | # Public key algorithm tests 16 | 17 | # Private keys used for PKEY operations. 18 | 19 | Title = X25519 test vectors (from RFC7748 6.1) 20 | 21 | PrivateKey=Alice-25519 22 | -----BEGIN PRIVATE KEY----- 23 | MC4CAQAwBQYDK2VuBCIEIHcHbQpzGKV9PBbBclGyZkXfTC+H68CZKrF3+6UduSwq 24 | -----END PRIVATE KEY----- 25 | 26 | PublicKey=Alice-25519-PUBLIC 27 | -----BEGIN PUBLIC KEY----- 28 | MCowBQYDK2VuAyEAhSDwCYkwp1R0i33ctD73Wg2/Og0mOBr066SpjqqbTmo= 29 | -----END PUBLIC KEY----- 30 | 31 | PrivPubKeyPair = Alice-25519:Alice-25519-PUBLIC 32 | 33 | PrivateKey=Bob-25519 34 | -----BEGIN PRIVATE KEY----- 35 | MC4CAQAwBQYDK2VuBCIEIF2rCH5iSopLeeF/i4OADuZvO7EpJhi2/Rwviyf/iODr 36 | -----END PRIVATE KEY----- 37 | 38 | PublicKey=Bob-25519-PUBLIC 39 | -----BEGIN PUBLIC KEY----- 40 | MCowBQYDK2VuAyEA3p7bfXt9wbTTW2HC7OQ1Nz+DQ8hbeGdNrfx+FG+IK08= 41 | -----END PUBLIC KEY----- 42 | 43 | #Raw versions of the same keys as above 44 | 45 | PrivateKeyRaw=Alice-25519-Raw:X25519:77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a 46 | 47 | PublicKeyRaw=Alice-25519-PUBLIC-Raw:X25519:8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a 48 | 49 | PrivPubKeyPair = Alice-25519-Raw:Alice-25519-PUBLIC-Raw 50 | 51 | PrivateKeyRaw=Bob-25519-Raw:X25519:5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb 52 | 53 | PublicKeyRaw=Bob-25519-PUBLIC-Raw:X25519:de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f 54 | 55 | PrivPubKeyPair = Bob-25519:Bob-25519-PUBLIC 56 | 57 | PrivPubKeyPair = Bob-25519-Raw:Bob-25519-PUBLIC-Raw 58 | 59 | Derive=Alice-25519 60 | PeerKey=Bob-25519-PUBLIC 61 | SharedSecret=4A5D9D5BA4CE2DE1728E3BF480350F25E07E21C947D19E3376F09B3C1E161742 62 | 63 | Derive=Bob-25519 64 | PeerKey=Alice-25519-PUBLIC 65 | SharedSecret=4A5D9D5BA4CE2DE1728E3BF480350F25E07E21C947D19E3376F09B3C1E161742 66 | 67 | Derive=Alice-25519-Raw 68 | PeerKey=Bob-25519-PUBLIC-Raw 69 | SharedSecret=4A5D9D5BA4CE2DE1728E3BF480350F25E07E21C947D19E3376F09B3C1E161742 70 | 71 | Derive=Bob-25519-Raw 72 | PeerKey=Alice-25519-PUBLIC-Raw 73 | SharedSecret=4A5D9D5BA4CE2DE1728E3BF480350F25E07E21C947D19E3376F09B3C1E161742 74 | 75 | # Illegal sign/verify operations with X25519 key 76 | 77 | Sign=Alice-25519 78 | Result = KEYOP_INIT_ERROR 79 | Reason = operation not supported for this keytype 80 | 81 | Verify=Alice-25519 82 | Result = KEYOP_INIT_ERROR 83 | Reason = operation not supported for this keytype 84 | 85 | Title = Test keypair mismatches 86 | 87 | PrivPubKeyPair = Alice-25519:Bob-25519-PUBLIC 88 | Result = KEYPAIR_MISMATCH 89 | 90 | PrivPubKeyPair = Bob-25519:Alice-25519-PUBLIC 91 | Result = KEYPAIR_MISMATCH 92 | -------------------------------------------------------------------------------- /EvpTestRecipes/3.0/evppkey_kdf_tls1_prf.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved. 3 | # 4 | # Licensed under the Apache License 2.0 (the "License"). You may not use 5 | # this file except in compliance with the License. You can obtain a copy 6 | # in the file LICENSE in the source distribution or at 7 | # https://www.openssl.org/source/license.html 8 | 9 | # Tests start with one of these keywords 10 | # Cipher Decrypt Derive Digest Encoding KDF MAC PBE 11 | # PrivPubKeyPair Sign Verify VerifyRecover 12 | # and continue until a blank line. Lines starting with a pound sign are ignored. 13 | 14 | Title = TLS1 PRF tests (from NIST test vectors) 15 | 16 | PKEYKDF = TLS1-PRF 17 | Ctrl.md = md:MD5-SHA1 18 | Ctrl.Secret = hexsecret:bded7fa5c1699c010be23dd06ada3a48349f21e5f86263d512c0c5cc379f0e780ec55d9844b2f1db02a96453513568d0 19 | Ctrl.label = seed:master secret 20 | Ctrl.client_random = hexseed:e5acaf549cd25c22d964c0d930fa4b5261d2507fad84c33715b7b9a864020693 21 | Ctrl.server_random = hexseed:135e4d557fdf3aa6406d82975d5c606a9734c9334b42136e96990fbd5358cdb2 22 | Output = 2f6962dfbc744c4b2138bb6b3d33054c5ecc14f24851d9896395a44ab3964efc2090c5bf51a0891209f46c1e1e998f62 23 | 24 | PKEYKDF = TLS1-PRF 25 | Ctrl.md = md:MD5-SHA1 26 | Ctrl.Secret = hexsecret:2f6962dfbc744c4b2138bb6b3d33054c5ecc14f24851d9896395a44ab3964efc2090c5bf51a0891209f46c1e1e998f62 27 | Ctrl.label = seed:key expansion 28 | Ctrl.server_random = hexseed:67267e650eb32444119d222a368c191af3082888dc35afe8368e638c828874be 29 | Ctrl.client_random = hexseed:d58a7b1cd4fedaa232159df652ce188f9d997e061b9bf48e83b62990440931f6 30 | Output = 3088825988e77fce68d19f756e18e43eb7fe672433504feaf99b3c503d9091b164f166db301d70c9fc0870b4a94563907bee1a61fb786cb717576890bcc51cb9ead97e01d0a2fea99c953377b195205ff07b369589178796edc963fd80fdbe518a2fc1c35c18ae8d 31 | 32 | # Missing secret. 33 | PKEYKDF = TLS1-PRF 34 | Ctrl.md = md:MD5-SHA1 35 | Ctrl.Seed = hexseed:02 36 | Output = 03 37 | Result = KDF_DERIVE_ERROR 38 | 39 | # PKEYKDF variants. 40 | 41 | PKEYKDF = TLS1-PRF 42 | Ctrl.md = md:SHA256 43 | Ctrl.Secret = hexsecret:f8938ecc9edebc5030c0c6a441e213cd24e6f770a50dda07876f8d55da062bcadb386b411fd4fe4313a604fce6c17fbc 44 | Ctrl.label = seed:master secret 45 | Ctrl.client_random = hexseed:36c129d01a3200894b9179faac589d9835d58775f9b5ea3587cb8fd0364cae8c 46 | Ctrl.server_random = hexseed:f6c9575ed7ddd73e1f7d16eca115415812a43c2b747daaaae043abfb50053fce 47 | Output = 202c88c00f84a17a20027079604787461176455539e705be730890602c289a5001e34eeb3a043e5d52a65e66125188bf 48 | 49 | PKEYKDF = TLS1-PRF 50 | Ctrl.md = md:SHA256 51 | Ctrl.Secret = hexsecret:202c88c00f84a17a20027079604787461176455539e705be730890602c289a5001e34eeb3a043e5d52a65e66125188bf 52 | Ctrl.label = seed:key expansion 53 | Ctrl.server_random = hexseed:ae6c806f8ad4d80784549dff28a4b58fd837681a51d928c3e30ee5ff14f39868 54 | Ctrl.client_random = hexseed:62e1fd91f23f558a605f28478c58cf72637b89784d959df7e946d3f07bd1b616 55 | Output = d06139889fffac1e3a71865f504aa5d0d2a2e89506c6f2279b670c3e1b74f531016a2530c51a3a0f7e1d6590d0f0566b2f387f8d11fd4f731cdd572d2eae927f6f2f81410b25e6960be68985add6c38445ad9f8c64bf8068bf9a6679485d966f1ad6f68b43495b10a683755ea2b858d70ccac7ec8b053c6bd41ca299d4e51928 56 | 57 | # As above but use long name for KDF 58 | PKEYKDF = tls1-prf 59 | Ctrl.md = md:SHA256 60 | Ctrl.Secret = hexsecret:202c88c00f84a17a20027079604787461176455539e705be730890602c289a5001e34eeb3a043e5d52a65e66125188bf 61 | Ctrl.label = seed:key expansion 62 | Ctrl.server_random = hexseed:ae6c806f8ad4d80784549dff28a4b58fd837681a51d928c3e30ee5ff14f39868 63 | Ctrl.client_random = hexseed:62e1fd91f23f558a605f28478c58cf72637b89784d959df7e946d3f07bd1b616 64 | Output = d06139889fffac1e3a71865f504aa5d0d2a2e89506c6f2279b670c3e1b74f531016a2530c51a3a0f7e1d6590d0f0566b2f387f8d11fd4f731cdd572d2eae927f6f2f81410b25e6960be68985add6c38445ad9f8c64bf8068bf9a6679485d966f1ad6f68b43495b10a683755ea2b858d70ccac7ec8b053c6bd41ca299d4e51928 65 | 66 | # Missing digest. 67 | PKEYKDF = TLS1-PRF 68 | Ctrl.Secret = hexsecret:01 69 | Ctrl.Seed = hexseed:02 70 | Output = 03 71 | Result = KDF_DERIVE_ERROR 72 | -------------------------------------------------------------------------------- /EvpTestRecipes/3.0/evppkey_rsa_engine.txt: -------------------------------------------------------------------------------- 1 | PrivateKey = RSA-2048 2 | -----BEGIN PRIVATE KEY----- 3 | MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDNAIHqeyrh6gbV 4 | n3xz2f+5SglhXC5Lp8Y2zvCN01M+wxhVJbAVx2m5mnfWclv5w1Mqm25fZifV+4UW 5 | B2jT3anL01l0URcX3D0wnS/EfuQfl+Mq23+d2GShxHZ6Zm7NcbwarPXnUX9LOFlP 6 | 6psF5C1a2pkSAIAT5FMWpNm7jtCGuI0odYusr5ItRqhotIXSOcm66w4rZFknEPQr 7 | LR6gpLSALAvsqzKPimiwBzvbVG/uqYCdKEmRKzkMFTK8finHZY+BdfrkbzQzL/h7 8 | yrPkBkm5hXeGnaDqcYNT8HInVIhpE2SHYNEivmduD8SD3SD/wxvalqMZZsmqLnWt 9 | A95H4cRPAgMBAAECggEAYCl6x5kbFnoG1rJHWLjL4gi+ubLZ7Jc4vYD5Ci41AF3X 10 | ziktnim6iFvTFv7x8gkTvArJDWsICLJBTYIQREHYYkozzgIzyPeApIs3Wv8C12cS 11 | IopwJITbP56+zM+77hcJ26GCgA2Unp5CFuC/81WDiPi9kNo3Oh2CdD7D+90UJ/0W 12 | glplejFpEuhpU2URfKL4RckJQF/KxV+JX8FdIDhsJu54yemQdQKaF4psHkzwwgDo 13 | qc+yfp0Vb4bmwq3CKxqEoc1cpbJ5CHXXlAfISzUjlcuBzD/tW7BDtp7eDAcgRVAC 14 | XO6MX0QBcLYSC7SOD3R7zY9SIRCFDfBDxCjf0YcFMQKBgQD2+WG0fLwDXTrt68fe 15 | hQqVa2Xs25z2B2QGPxWqSFU8WNly/mZ1BW413f3De/O58vYi7icTNyVoScm+8hdv 16 | 6PfD+LuRujdN1TuvPeyBTSvewQwf3IjN0Wh28mse36PwlBl+301C/x+ylxEDuJjK 17 | hZxCcocIaoQqtBC7ac8tNa9r4wKBgQDUfnJKf/QQSLJwwlJKQQGHi3MVm7c9PbwY 18 | eyIOY1s1NPluJDoYTZP4YLa/u2txwe2aHh9FhYMCPDAelqaSwaCLU9DsnKkQEA2A 19 | RR47fcagG6xK7O+N95iEa8I1oIy7os9MBoBMwRIZ6VYIxxTj8UMNSR+tu6MqV1Gg 20 | T5d0WDTJpQKBgCHyRSu5uV39AoyRS/eZ8cp36JqV1Q08FtOE+EVfi9evnrPfo9WR 21 | 2YQt7yNfdjCo5IwIj/ZkLhAXlFNakz4el2+oUJ/HKLLaDEoaCNf883q6rh/zABrK 22 | HcG7sF2d/7qhoJ9/se7zgjfZ68zHIrkzhDbd5xGREnmMJoCcGo3sQyBhAoGAH3UQ 23 | qmLC2N5KPFMoJ4H0HgLQ6LQCrnhDLkScSBEBYaEUA/AtAYgKjcyTgVLXlyGkcRpg 24 | esRHHr+WSBD5W+R6ReYEmeKfTJdzyDdzQE9gZjdyjC0DUbsDwybIu3OnIef6VEDq 25 | IXK7oUZfzDDcsNn4mTDoFaoff5cpqFfgDgM43VkCgYBNHw11b+d+AQmaZS9QqIt7 26 | aF3FvwCYHV0jdv0Mb+Kc1bY4c0R5MFpzrTwVmdOerjuuA1+9b+0Hwo3nBZM4eaBu 27 | SOamA2hu2OJWCl9q8fLCT69KqWDjghhvFe7c6aJJGucwaA3Uz3eLcPqoaCarMiNH 28 | fMkTd7GabVourqIZdgvu1Q== 29 | -----END PRIVATE KEY----- 30 | 31 | # Corresponding public key 32 | 33 | PublicKey = RSA-2048-PUBLIC 34 | -----BEGIN PUBLIC KEY----- 35 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzQCB6nsq4eoG1Z98c9n/ 36 | uUoJYVwuS6fGNs7wjdNTPsMYVSWwFcdpuZp31nJb+cNTKptuX2Yn1fuFFgdo092p 37 | y9NZdFEXF9w9MJ0vxH7kH5fjKtt/ndhkocR2emZuzXG8Gqz151F/SzhZT+qbBeQt 38 | WtqZEgCAE+RTFqTZu47QhriNKHWLrK+SLUaoaLSF0jnJuusOK2RZJxD0Ky0eoKS0 39 | gCwL7Ksyj4posAc721Rv7qmAnShJkSs5DBUyvH4px2WPgXX65G80My/4e8qz5AZJ 40 | uYV3hp2g6nGDU/ByJ1SIaRNkh2DRIr5nbg/Eg90g/8Mb2pajGWbJqi51rQPeR+HE 41 | TwIDAQAB 42 | -----END PUBLIC KEY----- 43 | 44 | Title = RSA wrong MGF1 digest 45 | 46 | Availablein = default 47 | Verify = RSA-2048 48 | Ctrl = rsa_padding_mode:pss 49 | Ctrl = rsa_pss_saltlen:0 50 | Ctrl = digest:sha256 51 | Ctrl = rsa_mgf1_md:sha1 52 | Input="0123456789ABCDEF0123456789ABCDEF" 53 | Output=4DE433D5844043EF08D354DA03CB29068780D52706D7D1E4D50EFB7D58C9D547D83A747DDD0635A96B28F854E50145518482CB49E963054621B53C60C498D07C16E9C2789C893CF38D4D86900DE71BDE463BD2761D1271E358C7480A1AC0BAB930DDF39602AD1BC165B5D7436B516B7A7858E8EB7AB1C420EEB482F4D207F0E462B1724959320A084E13848D11D10FB593E66BF680BF6D3F345FC3E9C3DE60ABBAC37E1C6EC80A268C8D9FC49626C679097AA690BC1AA662B95EB8DB70390861AA0898229F9349B4B5FDD030D4928C47084708A933144BE23BD3C6E661B85B2C0EF9ED36D498D5B7320E8194D363D4AD478C059BAE804181965E0B81B663158A 54 | Result = VERIFY_ERROR 55 | 56 | Title = RSA sign/verify no padding 57 | 58 | Availablein = default 59 | Sign = RSA-2048 60 | Ctrl = rsa_padding_mode:none 61 | Input = 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef 62 | Output = 64b0e9f9892371110c40ba5739dc0974002aa6e6160b481447c6819947c2d3b537a6e3775a85ae8ef75e000ca5498d772e3e797012ac8e462d72e567eb4afae0d1df72ffc84b3117045c58eb13aabb427fd6591577089dfa36d8d07ebd0670e4473683659b53b050c32397752cdee7c08de667f8de0ec01db01d440e433986e57ead2f877356b7d4985daf6c7ba09e46c061fe2372baa90cbd77557ef1143f46e27abf65c276f165a753e1f09e3719d1bfd8b32efe4aed2e97b502aa96ce472d3d91a09fae47b1a5103c448039ada73a57d7a001542bfb0b58c8b4bcb705a108a643434bb7ff997b58ba8b76425d7510aeff3e60f17af82191500517653fa5f3 63 | 64 | Availablein = default 65 | Verify = RSA-2048-PUBLIC 66 | Ctrl = rsa_padding_mode:none 67 | Input = 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef 68 | Output = 64b0e9f9892371110c40ba5739dc0974002aa6e6160b481447c6819947c2d3b537a6e3775a85ae8ef75e000ca5498d772e3e797012ac8e462d72e567eb4afae0d1df72ffc84b3117045c58eb13aabb427fd6591577089dfa36d8d07ebd0670e4473683659b53b050c32397752cdee7c08de667f8de0ec01db01d440e433986e57ead2f877356b7d4985daf6c7ba09e46c061fe2372baa90cbd77557ef1143f46e27abf65c276f165a753e1f09e3719d1bfd8b32efe4aed2e97b502aa96ce472d3d91a09fae47b1a5103c448039ada73a57d7a001542bfb0b58c8b4bcb705a108a643434bb7ff997b58ba8b76425d7510aeff3e60f17af82191500517653fa5f3 69 | 70 | Title = RSA parameter is not NULLt 71 | 72 | Availablein = default 73 | Verify = RSA-2048 74 | Ctrl = digest:sha1 75 | Input = "0123456789ABCDEF1234" 76 | Output = 3ec3fc29eb6e122bd7aa361cd09fe1bcbe85311096a7b9e4799cedfb2351ce0ab7fe4e75b4f6b37f67edd9c60c800f9ab941c0c157d7d880ca9de40c951d60fd293ae220d4bc510b1572d6e85a1bbbd8605b52e05f1c64fafdae59a1c2fbed214b7844d0134619de62851d5a0522e32e556e5950f3f97b8150e3f0dffee612c924201c27cd9bc8b423a71533380c276d3d59fcba35a2e80a1a192ec266a6c2255012cd86a349fe90a542b355fa3355b04da6cdf1df77f0e7bd44a90e880e1760266d233e465226f5db1c68857847d82072861ee266ddfc2e596845b77e1803274a579835ab5e4975d81d20b7df9cec7795489e4a2bdb8c1cf6a6b359945ac92c 77 | -------------------------------------------------------------------------------- /EvpTestRecipes/3.0/evppkey_rsa_provider.txt: -------------------------------------------------------------------------------- 1 | PrivateKey = RSA-2048 2 | -----BEGIN PRIVATE KEY----- 3 | MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDNAIHqeyrh6gbV 4 | n3xz2f+5SglhXC5Lp8Y2zvCN01M+wxhVJbAVx2m5mnfWclv5w1Mqm25fZifV+4UW 5 | B2jT3anL01l0URcX3D0wnS/EfuQfl+Mq23+d2GShxHZ6Zm7NcbwarPXnUX9LOFlP 6 | 6psF5C1a2pkSAIAT5FMWpNm7jtCGuI0odYusr5ItRqhotIXSOcm66w4rZFknEPQr 7 | LR6gpLSALAvsqzKPimiwBzvbVG/uqYCdKEmRKzkMFTK8finHZY+BdfrkbzQzL/h7 8 | yrPkBkm5hXeGnaDqcYNT8HInVIhpE2SHYNEivmduD8SD3SD/wxvalqMZZsmqLnWt 9 | A95H4cRPAgMBAAECggEAYCl6x5kbFnoG1rJHWLjL4gi+ubLZ7Jc4vYD5Ci41AF3X 10 | ziktnim6iFvTFv7x8gkTvArJDWsICLJBTYIQREHYYkozzgIzyPeApIs3Wv8C12cS 11 | IopwJITbP56+zM+77hcJ26GCgA2Unp5CFuC/81WDiPi9kNo3Oh2CdD7D+90UJ/0W 12 | glplejFpEuhpU2URfKL4RckJQF/KxV+JX8FdIDhsJu54yemQdQKaF4psHkzwwgDo 13 | qc+yfp0Vb4bmwq3CKxqEoc1cpbJ5CHXXlAfISzUjlcuBzD/tW7BDtp7eDAcgRVAC 14 | XO6MX0QBcLYSC7SOD3R7zY9SIRCFDfBDxCjf0YcFMQKBgQD2+WG0fLwDXTrt68fe 15 | hQqVa2Xs25z2B2QGPxWqSFU8WNly/mZ1BW413f3De/O58vYi7icTNyVoScm+8hdv 16 | 6PfD+LuRujdN1TuvPeyBTSvewQwf3IjN0Wh28mse36PwlBl+301C/x+ylxEDuJjK 17 | hZxCcocIaoQqtBC7ac8tNa9r4wKBgQDUfnJKf/QQSLJwwlJKQQGHi3MVm7c9PbwY 18 | eyIOY1s1NPluJDoYTZP4YLa/u2txwe2aHh9FhYMCPDAelqaSwaCLU9DsnKkQEA2A 19 | RR47fcagG6xK7O+N95iEa8I1oIy7os9MBoBMwRIZ6VYIxxTj8UMNSR+tu6MqV1Gg 20 | T5d0WDTJpQKBgCHyRSu5uV39AoyRS/eZ8cp36JqV1Q08FtOE+EVfi9evnrPfo9WR 21 | 2YQt7yNfdjCo5IwIj/ZkLhAXlFNakz4el2+oUJ/HKLLaDEoaCNf883q6rh/zABrK 22 | HcG7sF2d/7qhoJ9/se7zgjfZ68zHIrkzhDbd5xGREnmMJoCcGo3sQyBhAoGAH3UQ 23 | qmLC2N5KPFMoJ4H0HgLQ6LQCrnhDLkScSBEBYaEUA/AtAYgKjcyTgVLXlyGkcRpg 24 | esRHHr+WSBD5W+R6ReYEmeKfTJdzyDdzQE9gZjdyjC0DUbsDwybIu3OnIef6VEDq 25 | IXK7oUZfzDDcsNn4mTDoFaoff5cpqFfgDgM43VkCgYBNHw11b+d+AQmaZS9QqIt7 26 | aF3FvwCYHV0jdv0Mb+Kc1bY4c0R5MFpzrTwVmdOerjuuA1+9b+0Hwo3nBZM4eaBu 27 | SOamA2hu2OJWCl9q8fLCT69KqWDjghhvFe7c6aJJGucwaA3Uz3eLcPqoaCarMiNH 28 | fMkTd7GabVourqIZdgvu1Q== 29 | -----END PRIVATE KEY----- 30 | 31 | # Corresponding public key 32 | 33 | PublicKey = RSA-2048-PUBLIC 34 | -----BEGIN PUBLIC KEY----- 35 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzQCB6nsq4eoG1Z98c9n/ 36 | uUoJYVwuS6fGNs7wjdNTPsMYVSWwFcdpuZp31nJb+cNTKptuX2Yn1fuFFgdo092p 37 | y9NZdFEXF9w9MJ0vxH7kH5fjKtt/ndhkocR2emZuzXG8Gqz151F/SzhZT+qbBeQt 38 | WtqZEgCAE+RTFqTZu47QhriNKHWLrK+SLUaoaLSF0jnJuusOK2RZJxD0Ky0eoKS0 39 | gCwL7Ksyj4posAc721Rv7qmAnShJkSs5DBUyvH4px2WPgXX65G80My/4e8qz5AZJ 40 | uYV3hp2g6nGDU/ByJ1SIaRNkh2DRIr5nbg/Eg90g/8Mb2pajGWbJqi51rQPeR+HE 41 | TwIDAQAB 42 | -----END PUBLIC KEY----- 43 | 44 | Title = RSA wrong MGF1 digest 45 | 46 | Availablein = symcryptprovider 47 | Verify = RSA-2048 48 | Ctrl = rsa_padding_mode:pss 49 | Ctrl = rsa_pss_saltlen:0 50 | Ctrl = digest:sha256 51 | Ctrl = rsa_mgf1_md:sha1 52 | Input="0123456789ABCDEF0123456789ABCDEF" 53 | Output=4DE433D5844043EF08D354DA03CB29068780D52706D7D1E4D50EFB7D58C9D547D83A747DDD0635A96B28F854E50145518482CB49E963054621B53C60C498D07C16E9C2789C893CF38D4D86900DE71BDE463BD2761D1271E358C7480A1AC0BAB930DDF39602AD1BC165B5D7436B516B7A7858E8EB7AB1C420EEB482F4D207F0E462B1724959320A084E13848D11D10FB593E66BF680BF6D3F345FC3E9C3DE60ABBAC37E1C6EC80A268C8D9FC49626C679097AA690BC1AA662B95EB8DB70390861AA0898229F9349B4B5FDD030D4928C47084708A933144BE23BD3C6E661B85B2C0EF9ED36D498D5B7320E8194D363D4AD478C059BAE804181965E0B81B663158A 54 | Result = PKEY_CTRL_ERROR 55 | 56 | Title = RSA sign/verify no padding 57 | 58 | Availablein = symcryptprovider 59 | Sign = RSA-2048 60 | Ctrl = rsa_padding_mode:none 61 | Input = 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef 62 | Output = 64b0e9f9892371110c40ba5739dc0974002aa6e6160b481447c6819947c2d3b537a6e3775a85ae8ef75e000ca5498d772e3e797012ac8e462d72e567eb4afae0d1df72ffc84b3117045c58eb13aabb427fd6591577089dfa36d8d07ebd0670e4473683659b53b050c32397752cdee7c08de667f8de0ec01db01d440e433986e57ead2f877356b7d4985daf6c7ba09e46c061fe2372baa90cbd77557ef1143f46e27abf65c276f165a753e1f09e3719d1bfd8b32efe4aed2e97b502aa96ce472d3d91a09fae47b1a5103c448039ada73a57d7a001542bfb0b58c8b4bcb705a108a643434bb7ff997b58ba8b76425d7510aeff3e60f17af82191500517653fa5f3 63 | Result = PKEY_CTRL_ERROR 64 | 65 | Availablein = symcryptprovider 66 | Verify = RSA-2048-PUBLIC 67 | Ctrl = rsa_padding_mode:none 68 | Input = 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef 69 | Output = 64b0e9f9892371110c40ba5739dc0974002aa6e6160b481447c6819947c2d3b537a6e3775a85ae8ef75e000ca5498d772e3e797012ac8e462d72e567eb4afae0d1df72ffc84b3117045c58eb13aabb427fd6591577089dfa36d8d07ebd0670e4473683659b53b050c32397752cdee7c08de667f8de0ec01db01d440e433986e57ead2f877356b7d4985daf6c7ba09e46c061fe2372baa90cbd77557ef1143f46e27abf65c276f165a753e1f09e3719d1bfd8b32efe4aed2e97b502aa96ce472d3d91a09fae47b1a5103c448039ada73a57d7a001542bfb0b58c8b4bcb705a108a643434bb7ff997b58ba8b76425d7510aeff3e60f17af82191500517653fa5f3 70 | Result = PKEY_CTRL_ERROR 71 | 72 | Title = RSA parameter is not NULLt 73 | 74 | Availablein = symcryptprovider 75 | Verify = RSA-2048 76 | Ctrl = digest:sha1 77 | Input = "0123456789ABCDEF1234" 78 | Output = 3ec3fc29eb6e122bd7aa361cd09fe1bcbe85311096a7b9e4799cedfb2351ce0ab7fe4e75b4f6b37f67edd9c60c800f9ab941c0c157d7d880ca9de40c951d60fd293ae220d4bc510b1572d6e85a1bbbd8605b52e05f1c64fafdae59a1c2fbed214b7844d0134619de62851d5a0522e32e556e5950f3f97b8150e3f0dffee612c924201c27cd9bc8b423a71533380c276d3d59fcba35a2e80a1a192ec266a6c2255012cd86a349fe90a542b355fa3355b04da6cdf1df77f0e7bd44a90e880e1760266d233e465226f5db1c68857847d82072861ee266ddfc2e596845b77e1803274a579835ab5e4975d81d20b7df9cec7795489e4a2bdb8c1cf6a6b359945ac92c 79 | -------------------------------------------------------------------------------- /EvpTestRecipes/README.md: -------------------------------------------------------------------------------- 1 | # EVP tests 2 | 3 | The test recipes contained in this folder are intended to be used with the OpenSSL evp_test application. The application 4 | is produced in the _test_ folder when building OpenSSL from source. A small modification is also needed to test the engine 5 | and provider properly (see below). These recipes are a modified version of the 6 | [upstream EVP test recipes](https://github.com/openssl/openssl/tree/master/test/recipes/30-test_evp_data). 7 | The SymCrypt engine and provider don't support all the algorithms in the test files. These are left in the test files to validate algorithm fetching when the SymCrypt engine and/or provider are configured. 8 | 9 | Note that some tests under '3.0' are suffixed with 'provider' and 'engine'. These are intended to be run with the provider 10 | and engine configured respectively due to minor support differences. Additionally, the SymCrypt engine is always used for 11 | OpenSSL 3.0 ciphers if configured. 12 | 13 | ## Running 14 | 15 | The below steps assume you have some config file with the SymCrypt engine and/or provider configured. 16 | 17 | ### OpenSSL 1.1.1 18 | 19 | 1. Update evp_test.c to load the config in `setup_test()` 20 | 21 | ```diff 22 | @@ -2718,6 +2718,13 @@ int setup_tests(void) 23 | { 24 | size_t n = test_get_argument_count(); 25 | 26 | + if (!OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL)) 27 | + { 28 | + TEST_error("OPENSSL_init_crypto failed"); 29 | + TEST_openssl_errors(); 30 | + return 0; 31 | + } 32 | + 33 | if (n == 0) { 34 | TEST_error("Usage: %s file...", test_get_program_name()); 35 | return 0; 36 | ``` 37 | 38 | 2. Build evp_test 39 | 3. Run evp_test against test files in EvpTestRecipes/1.1.1 40 | 41 | ```console 42 | OPENSSL_CONF= \ 43 | test/evp_test /EvpTestRecipes/1.1.1/.txt 44 | ``` 45 | 46 | ### OpenSSL 3.0 47 | 48 | 1. Update evp_test.c to skip the IV check in the cipher tests for engines 49 | 50 | ```diff 51 | @@ -813,7 +813,8 @@ static int cipher_test_enc(EVP_TEST *t, int enc, 52 | } 53 | 54 | /* Check that we get the same IV back */ 55 | - if (expected->iv != NULL) { 56 | + if (expected->iv != NULL && 57 | + EVP_CIPHER_get0_provider(EVP_CIPHER_CTX_get0_cipher(ctx_base)) != NULL) { 58 | /* Some (e.g., GCM) tests use IVs longer than EVP_MAX_IV_LENGTH. */ 59 | unsigned char iv[128]; 60 | if (!TEST_true(EVP_CIPHER_CTX_get_updated_iv(ctx_base, iv, sizeof(iv))) 61 | ``` 62 | 63 | 2. Build evp_test 64 | 3. Run evp_test against test files in EvpTestRecipes/3.0 65 | 66 | ```console 67 | test/evp_test -config \/EvpTestRecipes/3.0/.txt 68 | ``` 69 | 70 | ## Tests 71 | 72 | ### OpenSSL 1.1.1 73 | 74 | | Test Name | Test File | 75 | |-----------|-----------| 76 | | Case Insensitive | evpcase.txt | 77 | | AES-CCM CAVS | evpccmcavs.txt | 78 | | Ciphers | evpciph.txt | 79 | | Digests | evpdigest.txt | 80 | | Key Derivation | evpkdf.txt | 81 | | MAC | evpmac.txt | 82 | | ECDH | evppkey_ecc.txt | 83 | | Sign/Verify | evppkey.txt | 84 | 85 | ### OpenSSL 3.0 86 | 87 | | Test Name | Test File | 88 | |-----------|-----------| 89 | | AES-CCM CAVS | evpciph_aes_ccm_cavs.txt | 90 | | AES (Engine) | evpciph_aes_engine.txt | 91 | | AES (Provider) | evpciph_aes_provider.txt | 92 | | HKDF | evpkdf_hkdf.txt | 93 | | KBKDF Counter (SP800-108) | evpkdf_kbkdf_counter.txt | 94 | | KBKDF KMAC (SP800-108)| evpkdf_kbkdf_kmac.txt | 95 | | SSHKDF | evpkdf_ssh.txt | 96 | | TLS1 PRF | evpkdf_tls11_prf.txt | 97 | | TLS1.2 PRF | evpkdf_tls12_prf.txt | 98 | | MAC | evpmac_common.txt | 99 | | HMAC MD5 (Engine) | evpmac_engine.txt | 100 | | DH | evppkey_dh.txt | 101 | | ECDH | evppkey_ecdh.txt | 102 | | ECDSA | evppkey_ecdsa.txt | 103 | | ECDSA (Named curves only)| evppkey_ecdsa_names.txt | 104 | | X25519 | evppkey_ecx.txt | 105 | | FFDHE | evppkey_ffdhe.txt | 106 | | RSA | evppkey_rsa_common.txt | 107 | | RSA (Engine) | evppkey_rsa_engine.txt | 108 | | RSA (Provider) | evppkey_rsa_provider.txt | 109 | | RSA (Additional) | evppkey_rsa.txt | 110 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SCOSSL - The SymCrypt engine and provider for OpenSSL 2 | 3 | The SymCrypt engine and provider for OpenSSL (SCOSSL) allow the use of OpenSSL with [SymCrypt](https://github.com/Microsoft/SymCrypt) as the provider 4 | for core cryptographic operations. The primary motivation for this is to support FIPS certification, as vanilla OpenSSL 1.1.1 does not have a FIPS-certified 5 | cryptographic module, and the OpenSSL 3 fips module is not certified on the FIPS 140-3 standard. 6 | 7 | - [SymCrypt Engine](./SymCryptEngine/) (OpenSSL 1.1.1) 8 | - [SymCrypt Provider](./SymCryptProvider/) (OpenSSL 3) 9 | 10 | ## Versioning and Servicing 11 | 12 | As of version 1.0.0, SCOSSL uses the versioning scheme defined by the [Semantic Versioning 2.0.0](https://semver.org/spec/v2.0.0.html) specification. This means: 13 | 14 | - Major version changes introduce ABI and/or API breaking changes 15 | - Minor version changes introduce backwards compatible additional functionality or improvements, and/or bug fixes 16 | - Patch version changes introduce backwards compatible bug fixes 17 | 18 | Regarding servicing, our strong recommendation is that distro vendors and application developers regularly 19 | update to the latest version of SymCrypt and SymCrypt engine/provider for both security fixes and 20 | functionality/performance improvements. 21 | 22 | We will support long-term servicing of specific releases for security fixes. Details of this plan will be 23 | released publicly in the future. 24 | 25 | # Building Instructions 26 | ## Compilation Instructions 27 | 28 | 1. Install libssl, or compile and install OpenSSL from source 29 | 2. Follow Linux build instructions from SymCrypt repository [SymCrypt](https://github.com/Microsoft/SymCrypt) to build the Linux SymCrypt module 30 | * You can either install the Linux SymCrypt module (i.e libsymcrypt.so* to /usr/lib/, and inc/* to /usr/include/), or 31 | * Copy the built module to the root of the SymCrypt-OpenSSL repo `cp /bin/module//LinuxUserMode//libsymcrypt.so ./` 32 | 3. `mkdir bin; cd bin` 33 | 4. `cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake-toolchain/LinuxUserMode-.cmake` 34 | * If you have not installed SymCrypt header files, you can also specify the root directory `-DSYMCRYPT_ROOT_DIR=` 35 | * If you want to link to a specific OpenSSL installation, you can also specify `-DOPENSSL_ROOT_DIR=` 36 | * Optionally, for a release build, specify `-DCMAKE_BUILD_TYPE=Release` 37 | 5. `cmake --build .` 38 | * Optionally specify `-jN` where N is the number of processes you wish to spawn for the build 39 | 40 | ## Run Samples 41 | ``` 42 | ./SslPlay/SslPlay 43 | ``` 44 | 45 | ## Contributing 46 | 47 | This project welcomes contributions and suggestions. Most contributions require you to agree to a 48 | Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us 49 | the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com. 50 | 51 | When you submit a pull request, a CLA bot will automatically determine whether you need to provide 52 | a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions 53 | provided by the bot. You will only need to do this once across all repos using our CLA. 54 | 55 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 56 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or 57 | contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. 58 | 59 | ## Trademarks 60 | 61 | This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft 62 | trademarks or logos is subject to and must follow 63 | [Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general). 64 | Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. 65 | Any use of third-party trademarks or logos are subject to those third-party's policies. 66 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Security 4 | 5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). 6 | 7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://docs.microsoft.com/en-us/previous-versions/tn-archive/cc751383(v=technet.10)), please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | **Please do not report security vulnerabilities through public GitHub issues.** 12 | 13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://msrc.microsoft.com/create-report). 14 | 15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://www.microsoft.com/en-us/msrc/pgp-key-msrc). 16 | 17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc). 18 | 19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 20 | 21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 22 | * Full paths of source file(s) related to the manifestation of the issue 23 | * The location of the affected source code (tag/branch/commit or direct URL) 24 | * Any special configuration required to reproduce the issue 25 | * Step-by-step instructions to reproduce the issue 26 | * Proof-of-concept or exploit code (if possible) 27 | * Impact of the issue, including how an attacker might exploit the issue 28 | 29 | This information will help us triage your report more quickly. 30 | 31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://microsoft.com/msrc/bounty) page for more details about our active programs. 32 | 33 | ## Preferred Languages 34 | 35 | We prefer all communications to be in English. 36 | 37 | ## Policy 38 | 39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://www.microsoft.com/en-us/msrc/cvd). 40 | 41 | -------------------------------------------------------------------------------- /ScosslCommon/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13.0) 2 | 3 | project(scossl_common_lib) 4 | 5 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -Wall -Wextra -Wno-unknown-pragmas -Wno-unused-function") 6 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -std=c++1y -Wall -Wextra -Wno-unused-function") 7 | 8 | find_package(OpenSSL REQUIRED) 9 | include_directories(${OPENSSL_INCLUDE_DIR}) 10 | 11 | set(SCOSSL_SOURCES 12 | ./src/scossl_helpers.c 13 | ./src/scossl_aes_aead.c 14 | ./src/scossl_dh.c 15 | ./src/scossl_ecc.c 16 | ./src/scossl_hkdf.c 17 | ./src/scossl_mac.c 18 | ./src/scossl_rsa.c 19 | ./src/scossl_sshkdf.c 20 | ./src/scossl_tls1prf.c 21 | ) 22 | 23 | add_library(scossl_common STATIC ${SCOSSL_SOURCES}) 24 | 25 | target_include_directories(scossl_common PUBLIC ./inc) 26 | target_include_directories(scossl_common PRIVATE ./src) 27 | 28 | set_target_properties(scossl_common PROPERTIES OUTPUT_NAME "scosslcommon") -------------------------------------------------------------------------------- /ScosslCommon/inc/scossl_dh.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include "scossl_helpers.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | typedef struct 12 | { 13 | BOOL initialized; 14 | PSYMCRYPT_DLKEY dlkey; 15 | } SCOSSL_DH_KEY_CTX; 16 | 17 | SCOSSL_DH_KEY_CTX *scossl_dh_new_key_ctx(void); 18 | void scossl_dh_free_key_ctx(_Inout_ SCOSSL_DH_KEY_CTX *ctx); 19 | SCOSSL_DH_KEY_CTX *scossl_dh_dup_key_ctx(_In_ SCOSSL_DH_KEY_CTX *ctx, BOOL copyGroup); 20 | 21 | SCOSSL_STATUS scossl_dh_import_keypair(_Inout_ SCOSSL_DH_KEY_CTX *ctx, int nBitsPriv, 22 | _In_ PCSYMCRYPT_DLGROUP pDlgroup, BOOL skipGroupValidation, 23 | _In_ const BIGNUM *privateKey, _In_ const BIGNUM *publicKey); 24 | SCOSSL_STATUS scossl_dh_generate_keypair(_Inout_ SCOSSL_DH_KEY_CTX *ctx, int nBitsPriv, 25 | _In_ PCSYMCRYPT_DLGROUP pDlgroup); 26 | 27 | SCOSSL_STATUS scossl_dh_init_static(void); 28 | void scossl_destroy_safeprime_dlgroups(void); 29 | 30 | PCSYMCRYPT_DLGROUP scossl_dh_get_known_group(_In_ PCSYMCRYPT_DLGROUP pDlGroup); 31 | SCOSSL_STATUS scossl_dh_get_group_by_nid(int dlGroupNid, _In_opt_ const BIGNUM* p, 32 | _Out_ PCSYMCRYPT_DLGROUP *ppDlGroup); 33 | int scossl_dh_get_group_nid(_In_ PCSYMCRYPT_DLGROUP pDlGroup); 34 | 35 | #ifdef __cplusplus 36 | } 37 | #endif -------------------------------------------------------------------------------- /ScosslCommon/inc/scossl_ecc.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include "scossl_helpers.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | // Largest supported curve is P521 => 66 * 2 byte SymCrypt signatures 12 | #define SCOSSL_ECDSA_MAX_SYMCRYPT_SIGNATURE_LEN (132) 13 | 14 | SCOSSL_STATUS scossl_ecc_init_static(); 15 | void scossl_ecc_destroy_ecc_curves(); 16 | 17 | // x25519 is a separate interface in the provider and not supported in the 18 | // engine, so there's no need to fetch the hidden group from an EC_GROUP. 19 | PCSYMCRYPT_ECURVE scossl_ecc_nid_to_symcrypt_curve(int groupNid); 20 | PCSYMCRYPT_ECURVE scossl_ecc_group_to_symcrypt_curve(_In_ const EC_GROUP *group); 21 | PCSYMCRYPT_ECURVE scossl_ecc_get_x25519_curve(); 22 | EC_GROUP *scossl_ecc_symcrypt_curve_to_ecc_group(_In_ PCSYMCRYPT_ECURVE pCurve); 23 | int scossl_ecc_get_curve_security_bits(_In_ PCSYMCRYPT_ECURVE curve); 24 | 25 | const char *scossl_ecc_get_curve_name(_In_ PCSYMCRYPT_ECURVE curve); 26 | SCOSSL_STATUS scossl_ec_point_to_pubkey(_In_ const EC_POINT* ecPoint, _In_ const EC_GROUP *ecGroup, _In_ BN_CTX* bnCtx, 27 | _Out_writes_bytes_(cbPublicKey) PBYTE pbPublicKey, SIZE_T cbPublicKey); 28 | 29 | SIZE_T scossl_ecdsa_size(_In_ PCSYMCRYPT_ECURVE curve); 30 | 31 | SCOSSL_STATUS scossl_ecdsa_sign(_In_ PSYMCRYPT_ECKEY key, _In_ PCSYMCRYPT_ECURVE curve, 32 | _In_reads_bytes_(cbHashValue) PCBYTE pbHashValue, SIZE_T cbHashValue, 33 | _Out_writes_bytes_opt_(*pcbSignature) PBYTE pbSignature, _Out_ unsigned int* pcbSignature); 34 | SCOSSL_STATUS scossl_ecdsa_verify(_In_ PSYMCRYPT_ECKEY key, _In_ PCSYMCRYPT_ECURVE curve, 35 | _In_reads_bytes_(cbHashValue) PCBYTE pbHashValue, SIZE_T cbHashValue, 36 | _In_reads_bytes_(pcbSignature) PCBYTE pbSignature, SIZE_T pcbSignature); 37 | 38 | #ifdef __cplusplus 39 | } 40 | #endif -------------------------------------------------------------------------------- /ScosslCommon/inc/scossl_hkdf.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include "scossl_helpers.h" 6 | 7 | #include 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | #define HKDF_MAXBUF 1024 14 | 15 | // These macros were renamed in OpenSSL 3. Common implementation 16 | // uses the new names. This mapping from new to old names is 17 | // needed until OpenSSL 1.1.1 builds are no longer needed. 18 | #ifndef EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND 19 | #define EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND 20 | #endif 21 | 22 | #ifndef EVP_KDF_HKDF_MODE_EXTRACT_ONLY 23 | #define EVP_KDF_HKDF_MODE_EXTRACT_ONLY EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY 24 | #endif 25 | 26 | #ifndef EVP_KDF_HKDF_MODE_EXPAND_ONLY 27 | #define EVP_KDF_HKDF_MODE_EXPAND_ONLY EVP_PKEY_HKDEF_MODE_EXPAND_ONLY 28 | #endif 29 | 30 | typedef struct 31 | { 32 | int mode; 33 | EVP_MD *md; 34 | PBYTE pbSalt; 35 | SIZE_T cbSalt; 36 | PBYTE pbKey; 37 | SIZE_T cbKey; 38 | BYTE info[HKDF_MAXBUF]; 39 | SIZE_T cbInfo; 40 | } SCOSSL_HKDF_CTX; 41 | 42 | SCOSSL_HKDF_CTX *scossl_hkdf_newctx(); 43 | SCOSSL_HKDF_CTX *scossl_hkdf_dupctx(_In_ SCOSSL_HKDF_CTX *ctx); 44 | void scossl_hkdf_freectx(_Inout_ SCOSSL_HKDF_CTX *ctx); 45 | 46 | SCOSSL_STATUS scossl_hkdf_reset(_Inout_ SCOSSL_HKDF_CTX *ctx); 47 | 48 | SCOSSL_STATUS scossl_hkdf_append_info(_Inout_ SCOSSL_HKDF_CTX *ctx, 49 | _In_reads_bytes_(cbInfo) PCBYTE pbInfo, SIZE_T cbInfo); 50 | 51 | SCOSSL_STATUS scossl_hkdf_derive(_In_ SCOSSL_HKDF_CTX *ctx, 52 | _Out_writes_bytes_(keylen) PBYTE key, SIZE_T keylen); 53 | 54 | #ifdef __cplusplus 55 | } 56 | #endif -------------------------------------------------------------------------------- /ScosslCommon/inc/scossl_mac.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include "scossl_helpers.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | typedef VOID SCOSSL_MAC_EXPANDED_KEY, *PSCOSSL_MAC_EXPANDED_KEY; 12 | typedef VOID SCOSSL_MAC_STATE, *PSCOSSL_MAC_STATE; 13 | 14 | typedef VOID (SYMCRYPT_CALL * PSYMCRYPT_MAC_KEY_COPY) (PSCOSSL_MAC_EXPANDED_KEY pSrc, PSCOSSL_MAC_EXPANDED_KEY pDst); 15 | typedef VOID (SYMCRYPT_CALL * PSYMCRYPT_MAC_STATE_COPY) (PSCOSSL_MAC_STATE pSrc, PSCOSSL_MAC_EXPANDED_KEY pExpandedKey, PSCOSSL_MAC_STATE pDst); 16 | 17 | // Structure for holding additional constant MAC functions and 18 | // properties needed by SCOSSL 19 | typedef struct 20 | { 21 | PSYMCRYPT_MAC_KEY_COPY keyCopyFunc; 22 | PSYMCRYPT_MAC_STATE_COPY stateCopyFunc; 23 | SIZE_T blockSize; 24 | } SCOSSL_MAC_EX, *PSCOSSL_MAC_EX; 25 | typedef const SCOSSL_MAC_EX *PCSCOSSL_MAC_EX; 26 | 27 | typedef struct 28 | { 29 | PSCOSSL_MAC_EXPANDED_KEY expandedKey; 30 | PSCOSSL_MAC_STATE macState; 31 | PCSYMCRYPT_MAC pMac; 32 | PCSCOSSL_MAC_EX pMacEx; 33 | PBYTE pbKey; 34 | SIZE_T cbKey; 35 | 36 | // Provider specific fields 37 | PVOID libctx; 38 | // Purely informational 39 | char* mdName; 40 | } SCOSSL_MAC_CTX; 41 | 42 | SCOSSL_MAC_CTX *scossl_mac_dupctx(_In_ SCOSSL_MAC_CTX *ctx); 43 | void scossl_mac_freectx(_Inout_ SCOSSL_MAC_CTX *ctx); 44 | 45 | SCOSSL_STATUS scossl_mac_set_hmac_md(_Inout_ SCOSSL_MAC_CTX *ctx, int mdNid); 46 | SCOSSL_STATUS scossl_mac_set_cmac_cipher(_Inout_ SCOSSL_MAC_CTX *ctx, _In_ const EVP_CIPHER *cipher); 47 | SCOSSL_STATUS scossl_mac_set_mac_key(_Inout_ SCOSSL_MAC_CTX *ctx, 48 | _In_reads_bytes_(cbMacKey) PCBYTE pbMacKey, SIZE_T cbMacKey); 49 | 50 | SCOSSL_STATUS scossl_mac_init(_Inout_ SCOSSL_MAC_CTX *ctx, 51 | _In_reads_bytes_(cbKey) PCBYTE pbKey, SIZE_T cbKey); 52 | SCOSSL_STATUS scossl_mac_update(_Inout_ SCOSSL_MAC_CTX *ctx, 53 | _In_reads_bytes_(cbData) PCBYTE pbData, SIZE_T cbData); 54 | SCOSSL_STATUS scossl_mac_final(_Inout_ SCOSSL_MAC_CTX *ctx, 55 | _Out_writes_bytes_opt_(*cbResult) PBYTE pbResult, _Out_ SIZE_T *cbResult, SIZE_T outsize); 56 | 57 | #ifdef __cplusplus 58 | } 59 | #endif -------------------------------------------------------------------------------- /ScosslCommon/inc/scossl_rsa.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include "scossl_helpers.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | typedef struct 12 | { 13 | BIGNUM *p; 14 | BIGNUM *q; 15 | BIGNUM *d; 16 | BIGNUM *dmp1; 17 | BIGNUM *dmq1; 18 | BIGNUM *iqmp; 19 | } SCOSSL_RSA_PRIVATE_EXPORT_PARAMS; 20 | 21 | typedef struct 22 | { 23 | BIGNUM *n; 24 | BIGNUM *e; 25 | SCOSSL_RSA_PRIVATE_EXPORT_PARAMS *privateParams; 26 | } SCOSSL_RSA_EXPORT_PARAMS; 27 | 28 | SCOSSL_STATUS scossl_rsa_pkcs1_sign(_In_ PSYMCRYPT_RSAKEY key, int mdnid, 29 | _In_reads_bytes_(cbHashValue) PCBYTE pbHashValue, SIZE_T cbHashValue, 30 | _Out_writes_bytes_(*pcbSignature) PBYTE pbSignature, _Out_ SIZE_T* pcbSignature); 31 | SCOSSL_STATUS scossl_rsa_pkcs1_verify(_In_ PSYMCRYPT_RSAKEY key, int mdnid, 32 | _In_reads_bytes_(cbHashValue) PCBYTE pbHashValue, SIZE_T cbHashValue, 33 | _In_reads_bytes_(pcbSignature) PCBYTE pbSignature, SIZE_T pcbSignature); 34 | 35 | SCOSSL_STATUS scossl_rsapss_sign(_In_ PSYMCRYPT_RSAKEY key, int mdnid, int cbSalt, 36 | _In_reads_bytes_(cbHashValue) PCBYTE pbHashValue, SIZE_T cbHashValue, 37 | _Out_writes_bytes_(*pcbSignature) PBYTE pbSignature, _Out_ SIZE_T* pcbSignature); 38 | SCOSSL_STATUS scossl_rsapss_verify(_In_ PSYMCRYPT_RSAKEY key, int mdnid, int cbSalt, 39 | _In_reads_bytes_(cbHashValue) PCBYTE pbHashValue, SIZE_T cbHashValue, 40 | _In_reads_bytes_(pcbSignature) PCBYTE pbSignature, SIZE_T pcbSignature); 41 | 42 | SCOSSL_STATUS scossl_rsa_encrypt(_In_ PSYMCRYPT_RSAKEY key, UINT padding, 43 | int mdnid, _In_reads_bytes_opt_(cbLabel) PCBYTE pbLabel, SIZE_T cbLabel, 44 | _In_reads_bytes_(cbSrc) PCBYTE pbSrc, SIZE_T cbSrc, 45 | _Out_writes_bytes_(*pcbDst) PBYTE pbDst, _Out_ INT32 *pcbDst, SIZE_T cbDst); 46 | 47 | SCOSSL_STATUS scossl_rsa_decrypt(_In_ PSYMCRYPT_RSAKEY key, UINT padding, 48 | int mdnid, _In_reads_bytes_opt_(cbLabel) PCBYTE pbLabel, SIZE_T cbLabel, 49 | _In_reads_bytes_(cbSrc) PCBYTE pbSrc, SIZE_T cbSrc, 50 | _Out_writes_bytes_(*pcbDst) PBYTE pbDst, _Out_ INT32 *pcbDst, SIZE_T cbDst); 51 | 52 | SCOSSL_RSA_EXPORT_PARAMS *scossl_rsa_new_export_params(BOOL includePrivate); 53 | void scossl_rsa_free_export_params(_In_ SCOSSL_RSA_EXPORT_PARAMS *rsaParam, BOOL freeParams); 54 | SCOSSL_STATUS scossl_rsa_export_key(_In_ PCSYMCRYPT_RSAKEY key, _Out_ SCOSSL_RSA_EXPORT_PARAMS *rsaParams); 55 | 56 | SIZE_T scossl_get_expected_hash_length(int mdnid); 57 | int scossl_rsa_pss_get_salt_max(_In_ PSYMCRYPT_RSAKEY key, SIZE_T cbHashValue); 58 | 59 | #ifdef __cplusplus 60 | } 61 | #endif -------------------------------------------------------------------------------- /ScosslCommon/inc/scossl_sshkdf.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include "scossl_helpers.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #define SSH_KDF_MAX_DIGEST_SIZE (512 / 8) 12 | 13 | typedef struct 14 | { 15 | PCSYMCRYPT_HASH pHash; 16 | PBYTE pbKey; 17 | SIZE_T cbKey; 18 | BYTE hashValue[SSH_KDF_MAX_DIGEST_SIZE]; 19 | SIZE_T cbHashValue; 20 | BYTE sessionId[SSH_KDF_MAX_DIGEST_SIZE]; 21 | SIZE_T cbSessionId; 22 | BYTE label; 23 | } SCOSSL_SSHKDF_CTX; 24 | 25 | SCOSSL_SSHKDF_CTX *scossl_sshkdf_newctx(); 26 | SCOSSL_SSHKDF_CTX *scossl_sshkdf_dupctx(_In_ SCOSSL_SSHKDF_CTX *ctx); 27 | void scossl_sshkdf_freectx(_Inout_ SCOSSL_SSHKDF_CTX *ctx); 28 | 29 | SCOSSL_STATUS scossl_sshkdf_reset(_Inout_ SCOSSL_SSHKDF_CTX *ctx); 30 | 31 | SCOSSL_STATUS scossl_sshkdf_derive(_In_ SCOSSL_SSHKDF_CTX *ctx, 32 | _Out_writes_bytes_(keylen) PBYTE key, SIZE_T keylen); 33 | 34 | #ifdef __cplusplus 35 | } 36 | #endif -------------------------------------------------------------------------------- /ScosslCommon/inc/scossl_tls1prf.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include "scossl_helpers.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #define TLS1_PRF_MAXBUF 1024 12 | 13 | typedef struct 14 | { 15 | BOOL isTlsPrf1_1; 16 | PCSYMCRYPT_MAC pHmac; 17 | PBYTE pbSecret; 18 | SIZE_T cbSecret; 19 | BYTE seed[TLS1_PRF_MAXBUF]; 20 | SIZE_T cbSeed; 21 | } SCOSSL_TLS1_PRF_CTX; 22 | 23 | SCOSSL_TLS1_PRF_CTX *scossl_tls1prf_newctx(); 24 | SCOSSL_TLS1_PRF_CTX *scossl_tls1prf_dupctx(_In_ SCOSSL_TLS1_PRF_CTX *ctx); 25 | void scossl_tls1prf_freectx(_Inout_ SCOSSL_TLS1_PRF_CTX *ctx); 26 | SCOSSL_STATUS scossl_tls1prf_reset(_Inout_ SCOSSL_TLS1_PRF_CTX *ctx); 27 | 28 | SCOSSL_STATUS scossl_tls1prf_append_seed(_Inout_ SCOSSL_TLS1_PRF_CTX *ctx, 29 | _In_reads_bytes_(cbSeed) PCBYTE pbSeed, SIZE_T cbSeed); 30 | 31 | SCOSSL_STATUS scossl_tls1prf_derive(_In_ SCOSSL_TLS1_PRF_CTX *ctx, 32 | _Out_writes_bytes_(keylen) PBYTE key, SIZE_T keylen); 33 | 34 | #ifdef __cplusplus 35 | } 36 | #endif -------------------------------------------------------------------------------- /ScosslCommon/src/scossl_hkdf.c: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include "scossl_hkdf.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | SCOSSL_HKDF_CTX *scossl_hkdf_newctx() 12 | { 13 | return OPENSSL_zalloc(sizeof(SCOSSL_HKDF_CTX)); 14 | } 15 | 16 | _Use_decl_annotations_ 17 | SCOSSL_HKDF_CTX *scossl_hkdf_dupctx(SCOSSL_HKDF_CTX *ctx) 18 | { 19 | SCOSSL_HKDF_CTX *copyCtx = OPENSSL_malloc(sizeof(SCOSSL_HKDF_CTX)); 20 | if (copyCtx != NULL) 21 | { 22 | if (ctx->pbSalt == NULL) 23 | { 24 | copyCtx->pbSalt = NULL; 25 | } 26 | else if ((copyCtx->pbSalt = OPENSSL_memdup(ctx->pbSalt, ctx->cbSalt)) == NULL) 27 | { 28 | scossl_hkdf_freectx(copyCtx); 29 | return NULL; 30 | } 31 | copyCtx->cbSalt = ctx->cbSalt; 32 | 33 | if (ctx->pbKey == NULL) 34 | { 35 | copyCtx->pbKey = NULL; 36 | } 37 | else if ((copyCtx->pbKey = OPENSSL_memdup(ctx->pbKey, ctx->cbKey)) == NULL) 38 | { 39 | scossl_hkdf_freectx(copyCtx); 40 | return NULL; 41 | } 42 | copyCtx->cbKey = ctx->cbKey; 43 | 44 | copyCtx->md = ctx->md; 45 | copyCtx->mode = ctx->mode; 46 | copyCtx->cbInfo = ctx->cbInfo; 47 | memcpy(copyCtx->info, ctx->info, ctx->cbInfo); 48 | } 49 | 50 | return copyCtx; 51 | } 52 | 53 | _Use_decl_annotations_ 54 | void scossl_hkdf_freectx(SCOSSL_HKDF_CTX *ctx) 55 | { 56 | if (ctx == NULL) 57 | return; 58 | 59 | OPENSSL_clear_free(ctx->pbSalt, ctx->cbSalt); 60 | OPENSSL_clear_free(ctx->pbKey, ctx->cbKey); 61 | OPENSSL_cleanse(ctx->info, ctx->cbInfo); 62 | OPENSSL_free(ctx); 63 | } 64 | 65 | _Use_decl_annotations_ 66 | SCOSSL_STATUS scossl_hkdf_reset(SCOSSL_HKDF_CTX *ctx) 67 | { 68 | OPENSSL_clear_free(ctx->pbSalt, ctx->cbSalt); 69 | OPENSSL_clear_free(ctx->pbKey, ctx->cbKey); 70 | OPENSSL_cleanse(ctx, sizeof(*ctx)); 71 | return SCOSSL_SUCCESS; 72 | } 73 | 74 | _Use_decl_annotations_ 75 | SCOSSL_STATUS scossl_hkdf_append_info(SCOSSL_HKDF_CTX *ctx, 76 | PCBYTE pbInfo, SIZE_T cbInfo) 77 | { 78 | if (cbInfo > HKDF_MAXBUF - ctx->cbInfo) 79 | { 80 | return SCOSSL_FAILURE; 81 | } 82 | 83 | memcpy(ctx->info + ctx->cbInfo, pbInfo, cbInfo); 84 | ctx->cbInfo += cbInfo; 85 | 86 | return SCOSSL_SUCCESS; 87 | } 88 | 89 | _Use_decl_annotations_ 90 | SCOSSL_STATUS scossl_hkdf_derive(SCOSSL_HKDF_CTX *ctx, 91 | PBYTE key, SIZE_T keylen) 92 | { 93 | SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR; 94 | PCSYMCRYPT_MAC symcryptHmacAlg = NULL; 95 | SYMCRYPT_HKDF_EXPANDED_KEY scExpandedKey; 96 | 97 | if (ctx->md == NULL) 98 | { 99 | SCOSSL_LOG_ERROR(SCOSSL_ERR_F_HKDF_DERIVE, ERR_R_INTERNAL_ERROR, 100 | "Missing Digest"); 101 | return SCOSSL_FAILURE; 102 | } 103 | 104 | if (ctx->pbKey == NULL) 105 | { 106 | SCOSSL_LOG_ERROR(SCOSSL_ERR_F_HKDF_DERIVE, ERR_R_INTERNAL_ERROR, 107 | "Missing Key"); 108 | return SCOSSL_FAILURE; 109 | } 110 | 111 | symcryptHmacAlg = scossl_get_symcrypt_hmac_algorithm(EVP_MD_type(ctx->md)); 112 | if (symcryptHmacAlg == NULL) 113 | { 114 | return SCOSSL_FAILURE; 115 | } 116 | 117 | switch (ctx->mode) 118 | { 119 | case EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND: 120 | scError = SymCryptHkdf( 121 | symcryptHmacAlg, 122 | ctx->pbKey, ctx->cbKey, 123 | ctx->pbSalt, ctx->cbSalt, 124 | ctx->info, ctx->cbInfo, 125 | key, keylen); 126 | if (scError != SYMCRYPT_NO_ERROR) 127 | { 128 | return SCOSSL_FAILURE; 129 | } 130 | break; 131 | case EVP_KDF_HKDF_MODE_EXTRACT_ONLY: 132 | scError = SymCryptHkdfExtractPrk( 133 | symcryptHmacAlg, 134 | ctx->pbKey, ctx->cbKey, 135 | ctx->pbSalt, ctx->cbSalt, 136 | key, keylen); 137 | if (scError != SYMCRYPT_NO_ERROR) 138 | { 139 | return SCOSSL_FAILURE; 140 | } 141 | break; 142 | case EVP_KDF_HKDF_MODE_EXPAND_ONLY: 143 | scError = SymCryptHkdfPrkExpandKey( 144 | &scExpandedKey, 145 | symcryptHmacAlg, 146 | ctx->pbKey, ctx->cbKey); 147 | if (scError != SYMCRYPT_NO_ERROR) 148 | { 149 | return SCOSSL_FAILURE; 150 | } 151 | 152 | scError = SymCryptHkdfDerive( 153 | &scExpandedKey, 154 | ctx->info, ctx->cbInfo, 155 | key, keylen); 156 | if (scError != SYMCRYPT_NO_ERROR) 157 | { 158 | return SCOSSL_FAILURE; 159 | } 160 | break; 161 | default: 162 | SCOSSL_LOG_ERROR(SCOSSL_ERR_F_HKDF_DERIVE, ERR_R_INTERNAL_ERROR, 163 | "Invalid Mode: %d", ctx->mode); 164 | return SCOSSL_FAILURE; 165 | } 166 | 167 | return SCOSSL_SUCCESS; 168 | } 169 | 170 | #ifdef __cplusplus 171 | } 172 | #endif -------------------------------------------------------------------------------- /ScosslCommon/src/scossl_sshkdf.c: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include "scossl_sshkdf.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | _Use_decl_annotations_ 12 | SCOSSL_SSHKDF_CTX *scossl_sshkdf_newctx() 13 | { 14 | return OPENSSL_zalloc(sizeof(SCOSSL_SSHKDF_CTX)); 15 | } 16 | 17 | _Use_decl_annotations_ 18 | SCOSSL_SSHKDF_CTX *scossl_sshkdf_dupctx(SCOSSL_SSHKDF_CTX *ctx) 19 | { 20 | SCOSSL_SSHKDF_CTX *copyCtx = OPENSSL_malloc(sizeof(SCOSSL_SSHKDF_CTX)); 21 | 22 | if (copyCtx != NULL) 23 | { 24 | *copyCtx = *ctx; 25 | copyCtx->pbKey = NULL; 26 | 27 | if (ctx->pbKey != NULL && 28 | (copyCtx->pbKey = OPENSSL_memdup(ctx->pbKey, ctx->cbKey)) == NULL) 29 | { 30 | scossl_sshkdf_freectx(copyCtx); 31 | copyCtx = NULL; 32 | } 33 | } 34 | 35 | return copyCtx; 36 | } 37 | 38 | _Use_decl_annotations_ 39 | void scossl_sshkdf_freectx(SCOSSL_SSHKDF_CTX *ctx) 40 | { 41 | if (ctx == NULL) 42 | return; 43 | 44 | OPENSSL_clear_free(ctx->pbKey, ctx->cbKey); 45 | OPENSSL_cleanse(ctx->hashValue, sizeof(ctx->hashValue)); 46 | OPENSSL_cleanse(ctx->sessionId, sizeof(ctx->sessionId)); 47 | OPENSSL_free(ctx); 48 | } 49 | 50 | _Use_decl_annotations_ 51 | SCOSSL_STATUS scossl_sshkdf_reset(SCOSSL_SSHKDF_CTX *ctx) 52 | { 53 | OPENSSL_clear_free(ctx->pbKey, ctx->cbKey); 54 | OPENSSL_cleanse(ctx, sizeof(*ctx)); 55 | return SCOSSL_SUCCESS; 56 | } 57 | 58 | _Use_decl_annotations_ 59 | SCOSSL_STATUS scossl_sshkdf_derive(SCOSSL_SSHKDF_CTX *ctx, 60 | PBYTE key, SIZE_T keylen) 61 | { 62 | SYMCRYPT_ERROR scError; 63 | 64 | if (!ctx->pHash || 65 | ctx->cbHashValue == 0) 66 | { 67 | SCOSSL_LOG_ERROR(SCOSSL_ERR_F_SSHKDF_DERIVE, ERR_R_INTERNAL_ERROR, 68 | "Missing Digest"); 69 | return SCOSSL_FAILURE; 70 | } 71 | 72 | if (!ctx->pbKey) 73 | { 74 | SCOSSL_LOG_ERROR(SCOSSL_ERR_F_SSHKDF_DERIVE, ERR_R_INTERNAL_ERROR, 75 | "Missing Key"); 76 | return SCOSSL_FAILURE; 77 | } 78 | 79 | if (ctx->cbSessionId == 0) 80 | { 81 | SCOSSL_LOG_ERROR(SCOSSL_ERR_F_SSHKDF_DERIVE, ERR_R_INTERNAL_ERROR, 82 | "Missing Session ID"); 83 | return SCOSSL_FAILURE; 84 | } 85 | 86 | if (ctx->label == 0) 87 | { 88 | SCOSSL_LOG_ERROR(SCOSSL_ERR_F_SSHKDF_DERIVE, ERR_R_INTERNAL_ERROR, 89 | "Missing Label"); 90 | return SCOSSL_FAILURE; 91 | } 92 | 93 | scError = SymCryptSshKdf( 94 | ctx->pHash, 95 | ctx->pbKey, ctx->cbKey, 96 | ctx->hashValue, ctx->cbHashValue, 97 | ctx->label, 98 | ctx->sessionId, ctx->cbSessionId, 99 | key, keylen); 100 | 101 | if (scError != SYMCRYPT_NO_ERROR) 102 | { 103 | SCOSSL_LOG_SYMCRYPT_ERROR(SCOSSL_ERR_F_SSHKDF_DERIVE, 104 | "SymCryptSshKdf failed", scError); 105 | return SCOSSL_FAILURE; 106 | } 107 | 108 | return SCOSSL_SUCCESS; 109 | } 110 | 111 | #ifdef __cplusplus 112 | } 113 | #endif -------------------------------------------------------------------------------- /ScosslCommon/src/scossl_tls1prf.c: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include "scossl_tls1prf.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | SCOSSL_TLS1_PRF_CTX *scossl_tls1prf_newctx() 12 | { 13 | return OPENSSL_zalloc(sizeof(SCOSSL_TLS1_PRF_CTX)); 14 | } 15 | 16 | _Use_decl_annotations_ 17 | SCOSSL_TLS1_PRF_CTX *scossl_tls1prf_dupctx(SCOSSL_TLS1_PRF_CTX *ctx) 18 | { 19 | SCOSSL_TLS1_PRF_CTX *copyCtx = OPENSSL_malloc(sizeof(SCOSSL_TLS1_PRF_CTX)); 20 | if (copyCtx != NULL) 21 | { 22 | if (ctx->pbSecret == NULL) 23 | { 24 | copyCtx->pbSecret = NULL; 25 | } 26 | else if ((copyCtx->pbSecret = OPENSSL_memdup(ctx->pbSecret, ctx->cbSecret)) == NULL) 27 | { 28 | scossl_tls1prf_freectx(copyCtx); 29 | return NULL; 30 | } 31 | 32 | copyCtx->isTlsPrf1_1 = ctx->isTlsPrf1_1; 33 | copyCtx->pHmac = ctx->pHmac; 34 | copyCtx->cbSecret = ctx->cbSecret; 35 | copyCtx->cbSeed = ctx->cbSeed; 36 | memcpy(copyCtx->seed, ctx->seed, ctx->cbSeed); 37 | } 38 | 39 | return copyCtx; 40 | } 41 | 42 | _Use_decl_annotations_ 43 | void scossl_tls1prf_freectx(SCOSSL_TLS1_PRF_CTX *ctx) 44 | { 45 | if (ctx == NULL) 46 | return; 47 | 48 | OPENSSL_clear_free(ctx->pbSecret, ctx->cbSecret); 49 | OPENSSL_cleanse(ctx->seed, ctx->cbSeed); 50 | OPENSSL_free(ctx); 51 | } 52 | 53 | _Use_decl_annotations_ 54 | SCOSSL_STATUS scossl_tls1prf_reset(SCOSSL_TLS1_PRF_CTX *ctx) 55 | { 56 | OPENSSL_clear_free(ctx->pbSecret, ctx->cbSecret); 57 | OPENSSL_cleanse(ctx, sizeof(*ctx)); 58 | return SCOSSL_SUCCESS; 59 | } 60 | 61 | _Use_decl_annotations_ 62 | SCOSSL_STATUS scossl_tls1prf_append_seed(SCOSSL_TLS1_PRF_CTX *ctx, 63 | PCBYTE pbSeed, SIZE_T cbSeed) 64 | { 65 | if (cbSeed > TLS1_PRF_MAXBUF - ctx->cbSeed ) 66 | { 67 | return SCOSSL_FAILURE; 68 | } 69 | 70 | memcpy(ctx->seed + ctx->cbSeed, pbSeed, cbSeed); 71 | ctx->cbSeed += cbSeed; 72 | 73 | return SCOSSL_SUCCESS; 74 | } 75 | 76 | _Use_decl_annotations_ 77 | SCOSSL_STATUS scossl_tls1prf_derive(SCOSSL_TLS1_PRF_CTX *ctx, 78 | PBYTE key, SIZE_T keylen) 79 | { 80 | SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR; 81 | 82 | if (ctx->pbSecret == NULL) 83 | { 84 | SCOSSL_LOG_ERROR(SCOSSL_ERR_F_TLS1PRF_DERIVE, ERR_R_INTERNAL_ERROR, 85 | "Missing Secret"); 86 | return SCOSSL_FAILURE; 87 | } 88 | 89 | if (ctx->isTlsPrf1_1) 90 | { 91 | // Special case to use TlsPrf1_1 to handle md5_sha1 92 | SCOSSL_LOG_INFO(SCOSSL_ERR_F_TLS1PRF_DERIVE, SCOSSL_ERR_R_NOT_FIPS_ALGORITHM, 93 | "Using hash algorithm MD5+SHA1 which is not FIPS compliant"); 94 | 95 | scError = SymCryptTlsPrf1_1( 96 | ctx->pbSecret, ctx->cbSecret, 97 | NULL, 0, 98 | ctx->seed, ctx->cbSeed, 99 | key, keylen); 100 | } 101 | else 102 | { 103 | if (ctx->pHmac == NULL) 104 | { 105 | SCOSSL_LOG_ERROR(SCOSSL_ERR_F_TLS1PRF_DERIVE, ERR_R_INTERNAL_ERROR, 106 | "Missing Digest"); 107 | return SCOSSL_FAILURE; 108 | } 109 | 110 | scError = SymCryptTlsPrf1_2( 111 | ctx->pHmac, 112 | ctx->pbSecret, ctx->cbSecret, 113 | NULL, 0, 114 | ctx->seed, ctx->cbSeed, 115 | key, keylen); 116 | } 117 | 118 | if (scError != SYMCRYPT_NO_ERROR) 119 | { 120 | SCOSSL_LOG_SYMCRYPT_ERROR(SCOSSL_ERR_F_TLS1PRF_DERIVE, 121 | "SymCryptTlsPrf1_x failed", scError); 122 | return SCOSSL_FAILURE; 123 | } 124 | 125 | return SCOSSL_SUCCESS; 126 | } 127 | 128 | #ifdef __cplusplus 129 | } 130 | #endif -------------------------------------------------------------------------------- /SslPlay/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13.0) 2 | 3 | project(SslPlay) 4 | 5 | find_package(OpenSSL REQUIRED) 6 | 7 | include_directories(${OPENSSL_INCLUDE_DIR}) 8 | 9 | add_executable (SslPlay 10 | SslPlay.cpp 11 | ) 12 | 13 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-deprecated-declarations") 14 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-declarations") 15 | 16 | if (SCOSSL_SSHKDF) 17 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DSCOSSL_SSHKDF") 18 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSCOSSL_SSHKDF") 19 | endif() 20 | 21 | 22 | add_dependencies(SslPlay scossl_common) 23 | 24 | target_link_directories(SslPlay PUBLIC ${CMAKE_BINARY_DIR} ${CMAKE_INSTALL_LIBDIR}) 25 | target_include_directories(SslPlay PUBLIC ${CMAKE_SOURCE_DIR}/SymCryptEngine/inc) 26 | target_include_directories(SslPlay PUBLIC ../ScosslCommon/inc) 27 | 28 | target_link_libraries(SslPlay PUBLIC scossl_dynamic ${OPENSSL_CRYPTO_LIBRARY}) 29 | target_link_libraries(SslPlay PRIVATE scossl_common) 30 | -------------------------------------------------------------------------------- /SymCryptEngine/README.md: -------------------------------------------------------------------------------- 1 | 2 | # SymCrypt Engine 3 | The SymCrypt engine leverages the [OpenSSL engine interface](https://www.openssl.org/docs/man1.0.2/man3/engine.html) to override the 4 | cryptographic implementations in OpenSSL's libcrypto.so with SymCrypt's implementations. The SymCrypt engine is intended for use with 5 | OpenSSL 1.1.1. Engines have been deprecated in OpenSSL 3 and have limited use for legacy functions. See the 6 | [SymCrypt provider](../SymCryptProvider/), which serves a similar purpose to the SymCrypt engine in OpenSSL 3. 7 | 8 | Where possible the SymCrypt engine will direct OpenSSL API calls to the SymCrypt FIPS module. In cases where SymCrypt cannot (currently) 9 | support an OpenSSL API, the best effort is made to fall-back to the default OpenSSL implementation of the given function. In a few cases 10 | the engine will instead fail the call completely, as re-routing to OpenSSL's implementation is not always easy, and as with any project 11 | we have to prioritize! 12 | 13 | **Important note:** The code in this repository is currently undergoing validation for use in Microsoft-internal products. At this time, it 14 | has not been tested for use in other environments and should not be considered production-ready. 15 | 16 | ## Algorithms that will be routed to a FIPS certifiable SymCrypt module with this version 17 | 18 | The following list is not necessarily exhaustive, and will be updated as more functionality is added to SCOSSL. 19 | Note that just because an algorithm is FIPS certifiable, does not mean it is recommended for use. SSH-KDF implementation is disabled by default and can be enabled by adding `-DSCOSSL_SSHKDF=1` argument to CMake. This algorithm also requires OpenSSL source code in the build process. 20 | 21 | + Key derivation 22 | + HKDF (SHA1, SHA2-256, SHA2-384, SHA2-512) 23 | + TLS 1.2 KDF (SHA1, SHA2-256, SHA2-384, SHA2-512) 24 | + SSH-KDF (SHA1, SHA2-256, SHA2-384, SHA2-512) 25 | + Key Agreement 26 | + ECDH (P256, P384, P521) 27 | + Finite Field DH (ffdhe2048, ffdhe3072, ffdhe4096, modp2048, modp3072, modp4096) 28 | + Hashing 29 | + SHA1 30 | + SHA2-256 31 | + SHA2-384 32 | + SHA2-512 33 | + Message Authentication 34 | + HMAC (SHA1, SHA2-256, SHA2-384, SHA2-512) 35 | + Symmetric 36 | + AES (128, 192, 256) 37 | + CBC, CCM, ECB, GCM 38 | + Asymmetric 39 | + RSA (2048, 3072, 4096) 40 | + PKCS1, OAEP, PSS 41 | + ECDSA (P256, P384, P521) 42 | 43 | ## Known cases where SCOSSL will fail rather than fallback to default OpenSSL 44 | 45 | 1. Use of unsupported digests in RSA signatures, TLS PRF, and HMAC 46 | 2. Use of multi-prime (more than 2-prime) RSA -------------------------------------------------------------------------------- /SymCryptEngine/dynamic/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13.0) 2 | 3 | project(scossl_engine_dynamic) 4 | 5 | set(DEFAULT_BUILD_TYPE "Release") 6 | 7 | include(GNUInstallDirs) 8 | 9 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wno-deprecated-declarations -Wno-unused-parameter -Wno-unknown-pragmas") 10 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1y -Wall -Wextra -Wno-deprecated-declarations -Wno-unused-parameter") 11 | 12 | find_package(OpenSSL REQUIRED) 13 | include_directories(${OPENSSL_INCLUDE_DIR}) 14 | 15 | find_library(SYMCRYPT_LIBRARY symcrypt PATHS ${CMAKE_SOURCE_DIR}) 16 | 17 | set(SCOSSL_SOURCES 18 | ../src/e_scossl.c 19 | ../src/e_scossl_ciphers.c 20 | ../src/e_scossl_dh.c 21 | ../src/e_scossl_digests.c 22 | ../src/e_scossl_dsa.c 23 | ../src/e_scossl_ecc.c 24 | ../src/e_scossl_rand.c 25 | ../src/e_scossl_rsa.c 26 | ../src/e_scossl_rsapss.c 27 | ../src/e_scossl_hkdf.c 28 | ../src/e_scossl_tls1prf.c 29 | ../src/e_scossl_hmac.c 30 | ) 31 | 32 | if (SCOSSL_SSHKDF) 33 | list(APPEND SCOSSL_SOURCES ../src/e_scossl_sshkdf.c) 34 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DSCOSSL_SSHKDF") 35 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSCOSSL_SSHKDF") 36 | endif() 37 | 38 | if (${OPENSSL_VERSION} VERSION_EQUAL 1) 39 | list(APPEND SCOSSL_SOURCES ../src/e_scossl_pkey_meths.c) 40 | endif() 41 | 42 | add_library(scossl_dynamic SHARED ${SCOSSL_SOURCES}) 43 | add_dependencies(scossl_dynamic scossl_common) 44 | 45 | set_target_properties(scossl_dynamic PROPERTIES PUBLIC_HEADER ../inc/e_scossl.h) 46 | # target_link_libraries(scossl_dynamic ${OPENSSL_CRYPTO_LIBRARY}) 47 | target_include_directories(scossl_dynamic PUBLIC ../inc) 48 | target_include_directories(scossl_dynamic PRIVATE ../src) 49 | target_include_directories(scossl_dynamic PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) 50 | target_include_directories(scossl_dynamic PUBLIC ../ScosslCommon/inc) 51 | 52 | # Remove default "lib" prefix from symcryptengine.so as OpenSSL engine is not a generic Linux .so 53 | set_target_properties(scossl_dynamic PROPERTIES PREFIX "") 54 | set_target_properties(scossl_dynamic PROPERTIES OUTPUT_NAME "symcryptengine") 55 | 56 | target_link_libraries(scossl_dynamic PRIVATE scossl_common) 57 | target_link_libraries(scossl_dynamic PUBLIC ${SYMCRYPT_LIBRARY}) 58 | target_link_libraries(scossl_dynamic PUBLIC ${OPENSSL_CRYPTO_LIBRARY}) 59 | 60 | if (NOT DEFINED OPENSSL_ENGINES) 61 | set(OPENSSL_ENGINES "${CMAKE_INSTALL_LIBDIR}/engines-1.1" CACHE PATH "Path to OpenSSL engines") 62 | endif() 63 | 64 | # Install the engine to the OpenSSL engines directory 65 | # NB: this won't work if the distro has a custom engines directory that doesn't match 66 | # the OpenSSL default. 67 | install( 68 | TARGETS scossl_dynamic 69 | LIBRARY DESTINATION "${OPENSSL_ENGINES}" 70 | PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) 71 | 72 | -------------------------------------------------------------------------------- /SymCryptEngine/dynamic/OpenSSLConfig.conf: -------------------------------------------------------------------------------- 1 | openssl_conf = openssl_init 2 | 3 | [ openssl_init ] 4 | engines = engine_section 5 | 6 | [ engine_section ] 7 | symcrypt = symcrypt_section 8 | 9 | [ symcrypt_section ] 10 | engine_id = symcrypt 11 | dynamic_path = /usr/local/ssl/lib/engines-1.1/symcryptengine.so 12 | default_algorithms = ALL -------------------------------------------------------------------------------- /SymCryptEngine/inc/e_scossl.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #include "scossl_helpers.h" 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | // SymCrypt-OpenSSL Engine Initialization. 16 | int SCOSSL_ENGINE_Initialize(); 17 | 18 | #ifdef __cplusplus 19 | } 20 | #endif 21 | -------------------------------------------------------------------------------- /SymCryptEngine/src/e_scossl_ciphers.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include "e_scossl.h" 6 | #include 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | // Initialize all of the _hidden_* cipher variables 13 | SCOSSL_STATUS e_scossl_ciphers_init_static(); 14 | 15 | // Using ENGINE e, populate cipher with the one asked for by nid. 16 | // If cipher is NULL, return a list of supported nids in the nids parameter. 17 | // Returns 1 on success, or 0 on error for cipher case, and number of nids in nids list case. 18 | _Success_(return > 0) 19 | int e_scossl_ciphers(_Inout_ ENGINE *e, _Out_ const EVP_CIPHER **cipher, 20 | _Out_ const int **nids, int nid); 21 | 22 | void e_scossl_destroy_ciphers(void); 23 | 24 | #ifdef __cplusplus 25 | } 26 | #endif 27 | -------------------------------------------------------------------------------- /SymCryptEngine/src/e_scossl_dh.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include "e_scossl.h" 6 | #include 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | extern int e_scossl_dh_idx; 13 | 14 | // Initialize all of the _hidden_* dh variables 15 | SCOSSL_STATUS e_scossl_dh_init_static(); 16 | 17 | // Generates public and private DH values. 18 | // Expects shared parameters dh->p and dh->g to be set. 19 | // Generates a random private DH key unless dh->priv_key set, and computes corresponding 20 | // public value dh->pub_key. 21 | // Returns 1 on success, 0 otherwise 22 | SCOSSL_STATUS e_scossl_dh_generate_key(_Inout_ DH* dh); 23 | 24 | // Computes the shared secret from the private DH value in dh and the other party's public 25 | // value in pub_key and stores it in key. key must point to DH_size(dh) bytes of memory. 26 | // Returns size of shared secret on success, or -1 on error. 27 | SCOSSL_RETURNLENGTH e_scossl_dh_compute_key(_Out_writes_bytes_(DH_size(dh)) unsigned char* key, _In_ const BIGNUM* pub_key, _In_ DH* dh); 28 | 29 | // Destroys instance of DH object. The memory for dh is not freed by this function. 30 | // Returns 1 on success, or 0 on error 31 | SCOSSL_STATUS e_scossl_dh_finish(_Inout_ DH* dh); 32 | 33 | // Frees internal SymCrypt safe-prime Dlgroups, only to be used on engine destruction. 34 | void e_scossl_destroy_safeprime_dlgroups(void); 35 | 36 | #ifdef __cplusplus 37 | } 38 | #endif 39 | -------------------------------------------------------------------------------- /SymCryptEngine/src/e_scossl_digests.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include "e_scossl.h" 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | // Initialize all of the _hidden_* digests variables 16 | SCOSSL_STATUS e_scossl_digests_init_static(); 17 | 18 | /* 19 | * Returns either the digest for 'nid', or a list of supported 'nids'. 20 | * If the framework wants the EVP_MD for 'nid', it will call 21 | * e_scossl_digests(e, &p_evp_digest, NULL, nid); (return zero for failure) 22 | * If the framework wants a list of supported 'nid's, it will call 23 | * e_scossl_digests(e, NULL, &p_nids, 0); (returns number of 'nids' or -1 for error) 24 | */ 25 | _Success_(return > 0) 26 | int e_scossl_digests(_Inout_ ENGINE *e, _Out_opt_ const EVP_MD **digest, 27 | _Out_opt_ const int **nids, int nid); 28 | 29 | void e_scossl_destroy_digests(void); 30 | 31 | #ifdef __cplusplus 32 | } 33 | #endif 34 | -------------------------------------------------------------------------------- /SymCryptEngine/src/e_scossl_dsa.c: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include "e_scossl_dsa.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | typedef DSA_SIG* (*PFN_DSA_meth_sign) (const unsigned char* dgst, int dlen, DSA* dsa); 12 | typedef int (*PFN_DSA_meth_sign_setup) (DSA* dsa, BN_CTX* ctx_in, BIGNUM** kinvp, BIGNUM** rp); 13 | typedef int (*PFN_DSA_meth_verify) (const unsigned char* dgst, int dgst_len, DSA_SIG* sig, DSA* dsa); 14 | typedef int (*PFN_DSA_meth_init)(DSA* dsa); 15 | typedef int (*PFN_DSA_meth_finish)(DSA* dsa); 16 | 17 | _Success_(return != NULL) 18 | DSA_SIG* e_scossl_dsa_sign(_In_reads_bytes_(dlen) const unsigned char* dgst, int dlen, _In_ DSA* dsa) 19 | { 20 | const DSA_METHOD* ossl_dsa_meth = DSA_OpenSSL(); 21 | PFN_DSA_meth_sign pfn_dsa_sign = DSA_meth_get_sign(ossl_dsa_meth); 22 | if (!pfn_dsa_sign) { 23 | return SCOSSL_FAILURE; 24 | } 25 | 26 | return pfn_dsa_sign(dgst, dlen, dsa); 27 | } 28 | 29 | SCOSSL_STATUS e_scossl_dsa_sign_setup(_In_ DSA* dsa, _In_ BN_CTX* ctx_in, 30 | _Out_ BIGNUM** kinvp, _Out_ BIGNUM** rp) 31 | { 32 | const DSA_METHOD* ossl_dsa_meth = DSA_OpenSSL(); 33 | PFN_DSA_meth_sign_setup pfn_dsa_sign_setup = DSA_meth_get_sign_setup(ossl_dsa_meth); 34 | if (!pfn_dsa_sign_setup) { 35 | return SCOSSL_FAILURE; 36 | } 37 | 38 | return pfn_dsa_sign_setup(dsa, ctx_in, kinvp, rp); 39 | } 40 | 41 | SCOSSL_STATUS e_scossl_dsa_verify(_In_reads_bytes_(dgst_len) const unsigned char* dgst, int dgst_len, 42 | _In_ DSA_SIG* sig, _In_ DSA* dsa) 43 | { 44 | const DSA_METHOD* ossl_dsa_meth = DSA_OpenSSL(); 45 | PFN_DSA_meth_verify pfn_dsa_verify = DSA_meth_get_verify(ossl_dsa_meth); 46 | if (!pfn_dsa_verify) { 47 | return SCOSSL_FAILURE; 48 | } 49 | 50 | return pfn_dsa_verify(dgst, dgst_len, sig, dsa); 51 | } 52 | 53 | SCOSSL_STATUS e_scossl_dsa_init(_Inout_ DSA* dsa) 54 | { 55 | const DSA_METHOD* ossl_dsa_meth = DSA_OpenSSL(); 56 | PFN_DSA_meth_init pfn_dsa_init = DSA_meth_get_init(ossl_dsa_meth); 57 | if (!pfn_dsa_init) { 58 | return SCOSSL_FAILURE; 59 | } 60 | 61 | return pfn_dsa_init(dsa); 62 | } 63 | 64 | SCOSSL_STATUS e_scossl_dsa_finish(_Inout_ DSA* dsa) 65 | { 66 | const DSA_METHOD* ossl_dsa_meth = DSA_OpenSSL(); 67 | PFN_DSA_meth_finish pfn_dsa_finish = DSA_meth_get_finish(ossl_dsa_meth); 68 | if (!pfn_dsa_finish) { 69 | return SCOSSL_FAILURE; 70 | } 71 | 72 | return pfn_dsa_finish(dsa); 73 | } 74 | 75 | 76 | #ifdef __cplusplus 77 | } 78 | #endif 79 | 80 | 81 | -------------------------------------------------------------------------------- /SymCryptEngine/src/e_scossl_dsa.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include "e_scossl.h" 6 | #include 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | 13 | // Computes a digital signature on the dlen byte message digest dgst using the private key dsa 14 | // and returns it in a newly allocated DSA_SIG structure. 15 | // Returns the signature on success, or NULL on error. 16 | _Success_(return != NULL) 17 | DSA_SIG* e_scossl_dsa_sign(_In_reads_bytes_(dlen) const unsigned char* dgst, int dlen, _In_ DSA* dsa); 18 | 19 | // Precalculates the DSA signature values k^-1 and r. 20 | // Returns 1 on success, or 0 on error. 21 | SCOSSL_STATUS e_scossl_dsa_sign_setup(_In_ DSA* dsa, _In_ BN_CTX* ctx_in, _Out_ BIGNUM** kinvp, _Out_ BIGNUM** rp); 22 | 23 | // Verifies that the signature sig matches a given message digest dgst of size dgst_len. 24 | // dsa is the signer's public key. 25 | // Returns 1 for a valid signature, 0 for an incorrect signature, and -1 on error. 26 | SCOSSL_STATUS e_scossl_dsa_verify(_In_reads_bytes_(dgst_len) const unsigned char* dgst, int dgst_len, _In_ DSA_SIG* sig, _In_ DSA* dsa); 27 | 28 | // Initializes a new DSA instance. 29 | // Returns 1 on success, or 0 on error 30 | SCOSSL_STATUS e_scossl_dsa_init(_Inout_ DSA* dsa); 31 | 32 | // Destroys instance of DSA object. The memory for dsa is not freed by this function. 33 | // Returns 1 on success, or 0 on error 34 | SCOSSL_STATUS e_scossl_dsa_finish(_Inout_ DSA* dsa); 35 | 36 | #ifdef __cplusplus 37 | } 38 | #endif 39 | -------------------------------------------------------------------------------- /SymCryptEngine/src/e_scossl_ecc.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include "e_scossl.h" 6 | #include 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | extern int e_scossl_eckey_idx; 13 | 14 | typedef int (*PFN_eckey_copy)(EC_KEY *dest, const EC_KEY *src); 15 | typedef int (*PFN_eckey_set_group)(EC_KEY *key, const EC_GROUP *grp); 16 | typedef int (*PFN_eckey_set_private)(EC_KEY *key, const BIGNUM *priv_key); 17 | typedef int (*PFN_eckey_set_public)(EC_KEY *key, const EC_POINT *pub_key); 18 | 19 | // Initialize all of the _hidden_* ecc variables 20 | SCOSSL_STATUS e_scossl_ecc_init_static(); 21 | 22 | // Frees SymCrypt-specific components of key 23 | void e_scossl_eckey_finish(_Inout_ EC_KEY *key); 24 | 25 | // Generates a new public and private key for the supplied key object. 26 | // key must have an EC_GROUP object associated with it before calling this function. 27 | // Returns 1 on success or 0 on error. 28 | SCOSSL_STATUS e_scossl_eckey_keygen(_Inout_ EC_KEY *key); 29 | 30 | // Computes shared secret psec and secret length pseclen using pub_key and ecdh. 31 | // Allocates psec on success. 32 | // Returns length of secret on success, or -1 on error. 33 | SCOSSL_RETURNLENGTH e_scossl_eckey_compute_key(_Out_writes_bytes_(*pseclen) unsigned char **psec, 34 | _Out_ size_t *pseclen, 35 | _In_ const EC_POINT *pub_key, 36 | _In_ const EC_KEY *ecdh); 37 | 38 | // Computes a digital signature of the dlen bytes hash value dgst using the private EC key eckey 39 | // and the optional pre-computed values kinv and r. The DER encoded signature is stored in sig and its length 40 | // is returned in siglen. (sig must point to ECDSA_size(eckey) bytes of memory). The parameter type is ignored. 41 | // Returns 1 on success or 0 on error. 42 | SCOSSL_STATUS e_scossl_eckey_sign(int type, 43 | _In_reads_bytes_(dlen) const unsigned char* dgst, 44 | int dlen, 45 | _Out_writes_bytes_(*siglen) unsigned char* sig, 46 | _Out_ unsigned int* siglen, 47 | _In_opt_ const BIGNUM* kinv, 48 | _In_opt_ const BIGNUM* r, 49 | _In_ EC_KEY* eckey); 50 | 51 | // Precomputes parts of signing operation. eckey is the private EC key and ctx_in is a pointer to BN_CTX 52 | // structure (or NULL). The precomputed values are returned in kinv and rp and can be used in a later call 53 | // to ECDSA_sign_ex or ECDSA_do_sign_ex. 54 | // Returns 1 on success or 0 on error. 55 | SCOSSL_STATUS e_scossl_eckey_sign_setup(_In_ EC_KEY* eckey, _In_ BN_CTX* ctx_in, _Out_ BIGNUM** kinvp, _Out_ BIGNUM** rp); 56 | 57 | // Computes a digital signature of the dgst_len bytes hash value dgst using the private EC key eckey 58 | // and the optional pre-computed values in_kinv and in_r. 59 | // Returns the signature in a newly allocated ECDSA_SIG structure, or NULL on error. 60 | ECDSA_SIG* e_scossl_eckey_sign_sig(_In_reads_bytes_(dgstlen) const unsigned char* dgst, int dgst_len, 61 | _In_opt_ const BIGNUM* in_kinv, _In_opt_ const BIGNUM* in_r, 62 | _In_ EC_KEY* eckey); 63 | 64 | // Verifies that the signature in sigbuf of size sig_len is a valid ECDSA signature of the hash value dgst 65 | // of size dgst_len using the public key eckey. The parameter type is ignored. 66 | // Returns 1 for a valid signature, 0 for an invalid signature, and -1 on error. 67 | SCOSSL_STATUS e_scossl_eckey_verify(int type, _In_reads_bytes_(dgst_len) const unsigned char* dgst, int dgst_len, 68 | _In_reads_bytes_(sig_len) const unsigned char* sigbuf, int sig_len, _In_ EC_KEY* eckey); 69 | 70 | // Verifies that the signature in sig is a valid ECDSA signature of the hash value dgst of size dgst_len 71 | // using the public key eckey. 72 | // Returns 1 for a valid signature, 0 for an invalid signature, and -1 on error. 73 | SCOSSL_STATUS e_scossl_eckey_verify_sig(_In_reads_bytes_(dgst_len) const unsigned char* dgst, int dgst_len, 74 | _In_ const ECDSA_SIG* sig, _In_ EC_KEY* eckey); 75 | 76 | // Frees internal SymCrypt curves, only to be used on engine destruction. 77 | void e_scossl_destroy_ecc_curves(void); 78 | 79 | #ifdef __cplusplus 80 | } 81 | #endif 82 | -------------------------------------------------------------------------------- /SymCryptEngine/src/e_scossl_hkdf.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include "e_scossl.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | // Allocate internal context and attach to ctx. 12 | // Returns SCOSSL_SUCCESS on success, or SCOSSL_FAILURE on error. 13 | SCOSSL_STATUS e_scossl_hkdf_init(_Inout_ EVP_PKEY_CTX *ctx); 14 | 15 | // Frees the internal context of ctx. 16 | void e_scossl_hkdf_cleanup(_Inout_ EVP_PKEY_CTX *ctx); 17 | 18 | // Sends a control operation to context ctx. type indicates which operation, and 19 | // p1 and p2 are optional parameters depending on which type is used. 20 | // Returns SCOSSL_SUCCESS on success, or SCOSSL_FAILURE on error, or SCOSSL_UNSUPPORTED on not supported. 21 | SCOSSL_STATUS e_scossl_hkdf_ctrl(_Inout_ EVP_PKEY_CTX *ctx, int type, int p1, _In_ void *p2); 22 | 23 | // Initializes context ctx. 24 | // Returns SCOSSL_SUCCESS on success, or SCOSSL_FAILURE on error. 25 | SCOSSL_STATUS e_scossl_hkdf_derive_init(_Inout_ EVP_PKEY_CTX *ctx); 26 | 27 | // Derives a shared secret using ctx. If key is NULL then the maximum size of the output buffer 28 | // is written to the keylen parameter. If key is not NULL, then keylen should contain the length of 29 | // the key buffer, the shared secret is written to key and the amount of data written to keylen. 30 | // Returns SCOSSL_SUCCESS on success, or SCOSSL_FAILURE or a negative value for failure. 31 | SCOSSL_STATUS e_scossl_hkdf_derive(_Inout_ EVP_PKEY_CTX *ctx, 32 | _Out_writes_opt_(*keylen) unsigned char *key, _Inout_ size_t *keylen); 33 | 34 | #ifdef __cplusplus 35 | } 36 | #endif 37 | -------------------------------------------------------------------------------- /SymCryptEngine/src/e_scossl_hmac.c: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include "scossl_mac.h" 6 | #include "e_scossl_hmac.h" 7 | 8 | #include 9 | #include 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | _Use_decl_annotations_ 16 | SCOSSL_STATUS e_scossl_hmac_init(EVP_PKEY_CTX *ctx) 17 | { 18 | SCOSSL_MAC_CTX *e_scossl_hmac_context; 19 | 20 | if ((e_scossl_hmac_context = OPENSSL_zalloc(sizeof(SCOSSL_MAC_CTX))) == NULL) 21 | { 22 | SCOSSL_LOG_ERROR(SCOSSL_ERR_F_ENG_HMAC_INIT, ERR_R_MALLOC_FAILURE, 23 | "OPENSSL_zalloc returned NULL"); 24 | return SCOSSL_FAILURE; 25 | } 26 | 27 | EVP_PKEY_CTX_set_data(ctx, e_scossl_hmac_context); 28 | 29 | return SCOSSL_SUCCESS; 30 | } 31 | 32 | _Use_decl_annotations_ 33 | void e_scossl_hmac_cleanup(EVP_PKEY_CTX *ctx) 34 | { 35 | SCOSSL_MAC_CTX *e_scossl_hmac_context = EVP_PKEY_CTX_get_data(ctx); 36 | scossl_mac_freectx(e_scossl_hmac_context); 37 | EVP_PKEY_CTX_set_data(ctx, NULL); 38 | } 39 | 40 | // The const modifier on src was added in OpenSSL 3, but is not expected 41 | // in OpenSSL 1.1.1. Building the Engine for OpenSSL 1.1.1 will generate 42 | // an incompatible pointer warning that can be safely ignored. 43 | _Use_decl_annotations_ 44 | SCOSSL_STATUS e_scossl_hmac_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src) 45 | { 46 | SCOSSL_MAC_CTX *src_ctx, *dst_ctx; 47 | 48 | if ((src_ctx = EVP_PKEY_CTX_get_data(src)) == NULL) 49 | { 50 | return SCOSSL_FAILURE; 51 | } 52 | 53 | if ((dst_ctx = scossl_mac_dupctx(src_ctx)) == NULL) 54 | { 55 | SCOSSL_LOG_ERROR(SCOSSL_ERR_F_ENG_HMAC_COPY, ERR_R_MALLOC_FAILURE, 56 | "scossl_hmac_dupctx returned NULL"); 57 | return SCOSSL_FAILURE; 58 | } 59 | 60 | EVP_PKEY_CTX_set_data(dst, dst_ctx); 61 | 62 | return SCOSSL_SUCCESS; 63 | } 64 | 65 | _Use_decl_annotations_ 66 | SCOSSL_STATUS e_scossl_hmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) 67 | { 68 | EVP_PKEY *pkey; 69 | ASN1_OCTET_STRING *key; 70 | SCOSSL_STATUS ret = SCOSSL_SUCCESS; 71 | SCOSSL_MAC_CTX *e_scossl_hmac_context = EVP_PKEY_CTX_get_data(ctx); 72 | 73 | switch (type) 74 | { 75 | case EVP_PKEY_CTRL_MD: 76 | // Expecting p2 of type EVP_MD* specifying the hash function to be used in HMAC 77 | if (p2 == NULL) { 78 | ret = SCOSSL_FAILURE; 79 | break; 80 | } 81 | ret = scossl_mac_set_hmac_md(e_scossl_hmac_context, EVP_MD_type(p2)); 82 | break; 83 | case EVP_PKEY_CTRL_SET_MAC_KEY: 84 | // p2 : pointer to the buffer containing the HMAC key, must not be NULL. 85 | // p1 : length of the key in bytes. p1 = -1 indicates p2 is a null-terminated string. 86 | ret = scossl_mac_set_mac_key(e_scossl_hmac_context, p2, p1); 87 | break; 88 | case EVP_PKEY_CTRL_DIGESTINIT: 89 | if ((pkey = EVP_PKEY_CTX_get0_pkey(ctx)) == NULL || 90 | (key = EVP_PKEY_get0(pkey)) == NULL) 91 | { 92 | ret = SCOSSL_FAILURE; 93 | break; 94 | } 95 | 96 | ret = scossl_mac_init(e_scossl_hmac_context, key->data, key->length); 97 | break; 98 | default: 99 | SCOSSL_LOG_ERROR(SCOSSL_ERR_F_ENG_HMAC_CTRL, SCOSSL_ERR_R_NOT_IMPLEMENTED, 100 | "SymCrypt Engine does not support ctrl type (%d)", type); 101 | ret = SCOSSL_UNSUPPORTED; 102 | } 103 | 104 | return ret; 105 | } 106 | 107 | _Use_decl_annotations_ 108 | SCOSSL_STATUS e_scossl_hmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) 109 | { 110 | SCOSSL_STATUS ret = SCOSSL_SUCCESS; 111 | SCOSSL_MAC_CTX *e_scossl_hmac_context = EVP_PKEY_CTX_get_data(ctx); 112 | ASN1_OCTET_STRING *key; 113 | 114 | if (e_scossl_hmac_context->pbKey == NULL) 115 | { 116 | ret = SCOSSL_FAILURE; 117 | goto end; 118 | } 119 | 120 | if ((key = ASN1_OCTET_STRING_new()) == NULL || 121 | !ASN1_OCTET_STRING_set(key, e_scossl_hmac_context->pbKey, e_scossl_hmac_context->cbKey)) 122 | { 123 | ret = SCOSSL_FAILURE; 124 | goto end; 125 | } 126 | 127 | EVP_PKEY_assign(pkey, EVP_PKEY_HMAC, key); 128 | 129 | end: 130 | 131 | return ret; 132 | } 133 | 134 | _Use_decl_annotations_ 135 | SCOSSL_STATUS e_scossl_hmac_update(EVP_MD_CTX *ctx, const void *data, size_t count) 136 | { 137 | return scossl_mac_update(EVP_PKEY_CTX_get_data(EVP_MD_CTX_pkey_ctx(ctx)), data, count); 138 | } 139 | 140 | _Use_decl_annotations_ 141 | SCOSSL_STATUS e_scossl_hmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mdctx) 142 | { 143 | EVP_MD_CTX_set_flags(mdctx, EVP_MD_CTX_FLAG_NO_INIT); 144 | 145 | EVP_MD_CTX_set_update_fn(mdctx, e_scossl_hmac_update); 146 | 147 | return SCOSSL_SUCCESS; 148 | } 149 | 150 | _Use_decl_annotations_ 151 | SCOSSL_STATUS e_scossl_hmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, EVP_MD_CTX *mdctx) 152 | { 153 | return scossl_mac_final(EVP_PKEY_CTX_get_data(ctx), sig, siglen, *siglen); 154 | } 155 | 156 | #ifdef __cplusplus 157 | } 158 | #endif 159 | -------------------------------------------------------------------------------- /SymCryptEngine/src/e_scossl_hmac.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include "e_scossl.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | // Allocate internal context and attach to ctx. 12 | // Returns SCOSSL_SUCCESS on success, or SCOSSL_FAILURE on error. 13 | SCOSSL_STATUS e_scossl_hmac_init(_Inout_ EVP_PKEY_CTX *ctx); 14 | 15 | // Frees the internal context of ctx. 16 | void e_scossl_hmac_cleanup(_Inout_ EVP_PKEY_CTX *ctx); 17 | 18 | // Makes a copy of internal context src 19 | SCOSSL_STATUS e_scossl_hmac_copy(_Out_ EVP_PKEY_CTX *dst, _In_ const EVP_PKEY_CTX *src); 20 | 21 | // Sends a control operation to context ctx. type indicates which operation, and 22 | // p1 and p2 are optional parameters depending on which type is used. 23 | // Returns SCOSSL_SUCCESS on success, or SCOSSL_FAILURE on error, or SCOSSL_UNSUPPORTED on not supported. 24 | SCOSSL_STATUS e_scossl_hmac_ctrl(_Inout_ EVP_PKEY_CTX *ctx, int type, int p1, _In_ void *p2); 25 | 26 | // Initializes pkey with the HMAC key from the internal context. 27 | SCOSSL_STATUS e_scossl_hmac_keygen(_In_ EVP_PKEY_CTX *ctx, _Inout_ EVP_PKEY *pkey); 28 | 29 | // Performs initialization on the mdctx object, such as setting the message update function. 30 | SCOSSL_STATUS e_scossl_hmac_signctx_init(_Inout_ EVP_PKEY_CTX *ctx, _In_ EVP_MD_CTX *mdctx); 31 | 32 | // Finalizes the HMAC computation by calling the resultFunc of the HMAC algorithm on the mac state 33 | // stored in the internal context. 34 | // If sig is NULL siglen is set to HMAC output length. 35 | // If sig is not NULL, the length siglen points to should not not be smaller than the HMAC output length. 36 | SCOSSL_STATUS e_scossl_hmac_signctx(_Inout_ EVP_PKEY_CTX *ctx, _Out_ unsigned char *sig, _Out_ size_t *siglen, _In_ EVP_MD_CTX *mdctx); 37 | 38 | #ifdef __cplusplus 39 | } 40 | #endif 41 | -------------------------------------------------------------------------------- /SymCryptEngine/src/e_scossl_pkey_meths.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include "e_scossl.h" 6 | #include 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | // Initialize all of the _hidden_* pkey method variables 13 | SCOSSL_STATUS e_scossl_pkey_methods_init_static(); 14 | 15 | // Return a list of supported nids if pmeth is NULL, or a particular pkey 16 | // method in pmeth determined by nid. Returns number of supported nids in the first case. 17 | // Returns 1 on success in second case, or 0 on failure. 18 | _Success_(return > 0) 19 | int e_scossl_pkey_methods(_Inout_ ENGINE *e, _Out_opt_ EVP_PKEY_METHOD **pmeth, 20 | _Out_opt_ const int **nids, int nid); 21 | 22 | // Destroys internal methods 23 | void e_scossl_destroy_pkey_methods(void); 24 | 25 | #ifdef __cplusplus 26 | } 27 | #endif 28 | -------------------------------------------------------------------------------- /SymCryptEngine/src/e_scossl_rand.c: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include "e_scossl_rand.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | // RAND_seed() returns SCOSSL_SUCCESS on success, SCOSSL_FAILURE otherwise. 12 | // Since an error internally is fatal, we always return SCOSSL_SUCCESS here. 13 | static SCOSSL_STATUS e_scossl_rand_seed(_In_reads_bytes_(num) const void *buf, _In_ int num) 14 | { 15 | SymCryptProvideEntropy(buf, num); 16 | return SCOSSL_SUCCESS; 17 | } 18 | 19 | // RAND_bytes() returns SCOSSL_SUCCESS on success, SCOSSL_FAILURE otherwise. 20 | // Since an error internally is fatal, we always return SCOSSL_SUCCESS here. 21 | static SCOSSL_STATUS e_scossl_rand_bytes(_Out_writes_bytes_(num) unsigned char *buf, _In_ int num) 22 | { 23 | SymCryptRandom(buf, num); 24 | return SCOSSL_SUCCESS; 25 | } 26 | 27 | // RAND_add() returns SCOSSL_SUCCESS on success, SCOSSL_FAILURE otherwise. 28 | // Since an error internally is fatal, we always return SCOSSL_SUCCESS here. 29 | static SCOSSL_STATUS e_scossl_rand_add(_In_reads_bytes_(num) const void *buf, _In_ int num, _In_ ossl_unused double randomness) 30 | { 31 | SymCryptProvideEntropy(buf, num); 32 | return SCOSSL_SUCCESS; 33 | } 34 | 35 | // RAND_pseudo_bytes() returns SCOSSL_SUCCESS if the bytes generated are cryptographically strong, 36 | // SCOSSL_FAILURE otherwise. 37 | // Since an error internally is fatal, we always return SCOSSL_SUCCESS here. 38 | static SCOSSL_STATUS e_scossl_rand_pseudorand(_Out_writes_bytes_(num) unsigned char *buf, _In_ int num) 39 | { 40 | SymCryptRandom(buf, num); 41 | return SCOSSL_SUCCESS; 42 | } 43 | 44 | // RAND_status() returns SCOSSL_SUCCESS if the PRNG has been seeded with enough data, SCOSSL_FAILURE 45 | // otherwise. 46 | // Since we guarantee this, we return always return SCOSSL_SUCCESS here. 47 | static SCOSSL_STATUS e_scossl_rand_status(void) 48 | { 49 | return SCOSSL_SUCCESS; 50 | } 51 | 52 | RAND_METHOD _e_scossl_rand_meth = { 53 | e_scossl_rand_seed, 54 | e_scossl_rand_bytes, 55 | NULL, 56 | e_scossl_rand_add, 57 | e_scossl_rand_pseudorand, 58 | e_scossl_rand_status 59 | }; 60 | 61 | RAND_METHOD *e_scossl_rand_method(void) 62 | { 63 | return &_e_scossl_rand_meth; 64 | } 65 | 66 | #ifdef __cplusplus 67 | } 68 | #endif 69 | 70 | 71 | -------------------------------------------------------------------------------- /SymCryptEngine/src/e_scossl_rand.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include "e_scossl.h" 6 | #include 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | RAND_METHOD *e_scossl_rand_method(void); 13 | 14 | #ifdef __cplusplus 15 | } 16 | #endif 17 | -------------------------------------------------------------------------------- /SymCryptEngine/src/e_scossl_rsa.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include "e_scossl.h" 6 | #include "scossl_rsa.h" 7 | #include 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | extern int e_scossl_rsa_idx; 14 | 15 | // Public Encryption 16 | // Encrypts flen bytes at from using public key rsa and stores ciphertext in to. 17 | // Same parameters as RSA_public_encrypt 18 | // - flen must not be more than RSA_size(rsa) - 11 for the PKCS #1 v1.5 based padding modes, not more than RSA_size(rsa) - 42 19 | // for RSA_PKCS1_OAEP_PADDING and exactly RSA_size(rsa) for RSA_NO_PADDING 20 | // - from and to may overlap 21 | // - padding is ones of RSA_PKCS1_PADDING, RSA_PKCS1_OAEP_PADDING, RSA_SSLV23_PADDING, or RSA_NO_PADDING 22 | // Returns size of encrypted data (RSA_size(rsa)), or -1 on error 23 | SCOSSL_RETURNLENGTH e_scossl_rsa_pub_enc(int flen, _In_reads_bytes_(flen) const unsigned char* from, 24 | _Out_writes_bytes_(RSA_size(rsa)) unsigned char* to, _In_ RSA* rsa, 25 | int padding); 26 | 27 | // Private Decryption 28 | // Decrypts flen bytes at from using private key rsa and stores plaintext in to. 29 | // Same parameters as RSA_private_decrypt 30 | // - flen should be equal to RSA_size(rsa) but may be smaller, when leading zero bytes are in the ciphertext 31 | // - from and to may overlap 32 | // - padding is the mode used to encrypt the data 33 | // Returns size of recovered plaintext, or -1 on error. 34 | SCOSSL_RETURNLENGTH e_scossl_rsa_priv_dec(int flen, _In_reads_bytes_(flen) const unsigned char* from, 35 | _Out_writes_bytes_(RSA_size(rsa)) unsigned char* to, _In_ RSA* rsa, int padding); 36 | 37 | // Private Encryption 38 | // Signs flen bytes at from using private key rsa and stores signature in to. 39 | // Returns size of signature, or -1 on error 40 | SCOSSL_RETURNLENGTH e_scossl_rsa_priv_enc(int flen, _In_reads_bytes_(flen) const unsigned char* from, 41 | _Out_writes_bytes_(RSA_size(rsa)) unsigned char* to, _In_ RSA* rsa, int padding); 42 | 43 | // Public Decryption 44 | // Recovers message digest from flen-bytes long signature at from using public key rsa and stores result in to. 45 | // Returns size of recovered message digest, or -1 on error. 46 | SCOSSL_RETURNLENGTH e_scossl_rsa_pub_dec(int flen, _In_reads_bytes_(flen) const unsigned char* from, 47 | _Out_writes_bytes_(RSA_size(rsa)) unsigned char* to, _In_ RSA* rsa, 48 | int padding); 49 | 50 | // Used for CRT computations, used by default RSA implementations 51 | // ctx is a temporary BIGNUM variable 52 | // Returns SCOSSL_SUCCESS on success, or SCOSSL_FAILURE on error 53 | SCOSSL_STATUS e_scossl_rsa_mod_exp(_Out_ BIGNUM* r0, _In_ const BIGNUM* i, _In_ RSA* rsa, _In_ BN_CTX* ctx); 54 | 55 | // Used for CRT computations, used by default RSA implementations 56 | // r = a ^ p mod m 57 | // ctx is a temporary BIGNUM variable, while m_ctx is a Montgomery multiplication structure 58 | // Returns SCOSSL_SUCCESS on success, or SCOSSL_FAILURE on error 59 | SCOSSL_STATUS e_scossl_rsa_bn_mod_exp(_Out_ BIGNUM* r, _In_ const BIGNUM* a, _In_ const BIGNUM* p, 60 | _In_ const BIGNUM* m, _In_ BN_CTX* ctx, _In_ BN_MONT_CTX* m_ctx); 61 | 62 | // Signs the message digest m of size m_len using private key rsa using PKCS1-v1_5 and stores signature in sigret and 63 | // signature size in siglen. Type denotes the message digest algorithm used to generate m. 64 | // Returns SCOSSL_SUCCESS on success, or SCOSSL_FAILURE on error 65 | SCOSSL_STATUS e_scossl_rsa_sign(int type, _In_reads_bytes_(m_length) const unsigned char* m, unsigned int m_length, 66 | _Out_writes_bytes_(siglen) unsigned char* sigret, _Out_ unsigned int* siglen, 67 | _In_ const RSA* rsa); 68 | 69 | // Verifies that the signature sigbuf of size siglen matches a given message digest m of size m_len. 70 | // dtype denotes the message digest algorithm that was used to generate the signature. rsa is the signer's 71 | // public key. 72 | // Returns SCOSSL_SUCCESS on successful verification, or SCOSSL_FAILURE on error 73 | SCOSSL_STATUS e_scossl_rsa_verify(int dtype, _In_reads_bytes_(m_length) const unsigned char* m, 74 | unsigned int m_length, 75 | _In_reads_bytes_(siglen) const unsigned char* sigbuf, 76 | unsigned int siglen, _In_ const RSA* rsa); 77 | 78 | // Generates a 2-prime RSA key pair and stores it in rsa. Modulus will be of length bits, 79 | // the number of primes to form the modulus will be primes, and the public exponent will be e. 80 | // cb is an optional callback for progress of key generation that is unused in our implementation. 81 | // Returns SCOSSL_SUCCESS on success, or SCOSSL_FAILURE on error 82 | SCOSSL_STATUS e_scossl_rsa_keygen(_Out_ RSA* rsa, int bits, _In_ BIGNUM* e, _In_opt_ BN_GENCB* cb); 83 | 84 | // Initializes a new RSA instance. 85 | // Returns SCOSSL_SUCCESS on success, or SCOSSL_FAILURE on error 86 | SCOSSL_STATUS e_scossl_rsa_init(_Inout_ RSA *rsa); 87 | 88 | // Destroys instance of RSA object. The memory for rsa is not freed by this function. 89 | // Returns SCOSSL_SUCCESS on success, or SCOSSL_FAILURE on error 90 | SCOSSL_STATUS e_scossl_rsa_finish(_Inout_ RSA *rsa); 91 | 92 | typedef struct _SCOSSL_RSA_KEY_CONTEXT { 93 | int initialized; 94 | PSYMCRYPT_RSAKEY key; 95 | } SCOSSL_RSA_KEY_CONTEXT; 96 | 97 | // Initializes keyCtx from key rsa. 98 | // Returns SCOSSL_SUCCESS on success, or SCOSSL_FAILURE on error 99 | SCOSSL_STATUS e_scossl_initialize_rsa_key(_In_ const RSA* rsa, _Out_ SCOSSL_RSA_KEY_CONTEXT *keyCtx); 100 | 101 | // Frees data and key of keyCtx 102 | void e_scossl_rsa_free_key_context(_In_ SCOSSL_RSA_KEY_CONTEXT *keyCtx); 103 | 104 | #ifdef __cplusplus 105 | } 106 | #endif 107 | -------------------------------------------------------------------------------- /SymCryptEngine/src/e_scossl_rsapss.c: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include "e_scossl_rsa.h" 6 | #include 7 | #include 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | SCOSSL_STATUS e_scossl_rsapss_sign(_Inout_ EVP_PKEY_CTX *ctx, _Out_writes_opt_(*siglen) unsigned char *sig, _Out_ size_t *siglen, 14 | _In_reads_bytes_(tbslen) const unsigned char *tbs, size_t tbslen) 15 | { 16 | EVP_PKEY* pkey = NULL; 17 | const RSA* rsa = NULL; 18 | SCOSSL_RSA_KEY_CONTEXT *keyCtx = NULL; 19 | const EVP_MD *messageDigest; 20 | const EVP_MD *mgf1Digest; 21 | int type = 0; 22 | int cbSalt = RSA_PSS_SALTLEN_DIGEST; 23 | 24 | if( EVP_PKEY_CTX_get_signature_md(ctx, &messageDigest) <= 0 ) 25 | { 26 | SCOSSL_LOG_ERROR(SCOSSL_ERR_F_ENG_RSAPSS_SIGN, ERR_R_OPERATION_FAIL, 27 | "Failed to get messageDigest"); 28 | return SCOSSL_UNSUPPORTED; 29 | } 30 | if( EVP_PKEY_CTX_get_rsa_mgf1_md(ctx, &mgf1Digest) <= 0 ) 31 | { 32 | SCOSSL_LOG_ERROR(SCOSSL_ERR_F_ENG_RSAPSS_SIGN, ERR_R_OPERATION_FAIL, 33 | "Failed to get mgf1Digest"); 34 | return SCOSSL_UNSUPPORTED; 35 | } 36 | type = EVP_MD_type(messageDigest); 37 | 38 | if( type != EVP_MD_type(mgf1Digest) ) 39 | { 40 | SCOSSL_LOG_ERROR(SCOSSL_ERR_F_ENG_RSAPSS_SIGN, SCOSSL_ERR_R_NOT_IMPLEMENTED, 41 | "messageDigest and mgf1Digest do not match"); 42 | return SCOSSL_UNSUPPORTED; 43 | } 44 | 45 | if( ((pkey = EVP_PKEY_CTX_get0_pkey(ctx)) == NULL) || 46 | ((rsa = EVP_PKEY_get0_RSA(pkey)) == NULL) ) 47 | { 48 | SCOSSL_LOG_ERROR(SCOSSL_ERR_F_ENG_RSAPSS_SIGN, SCOSSL_ERR_R_MISSING_CTX_DATA, 49 | "Failed to get RSA key from ctx"); 50 | return SCOSSL_UNSUPPORTED; 51 | } 52 | 53 | if( EVP_PKEY_CTX_get_rsa_pss_saltlen(ctx, &cbSalt) <= 0 ) 54 | { 55 | SCOSSL_LOG_ERROR(SCOSSL_ERR_F_ENG_RSAPSS_SIGN, ERR_R_OPERATION_FAIL, 56 | "Failed to get cbSalt"); 57 | return SCOSSL_UNSUPPORTED; 58 | } 59 | 60 | keyCtx = RSA_get_ex_data(rsa, e_scossl_rsa_idx); 61 | if( keyCtx == NULL ) 62 | { 63 | SCOSSL_LOG_ERROR(SCOSSL_ERR_F_ENG_RSAPSS_SIGN, SCOSSL_ERR_R_MISSING_CTX_DATA, 64 | "SymCrypt Context Not Found."); 65 | return SCOSSL_FAILURE; 66 | } 67 | if( keyCtx->initialized == 0 ) 68 | { 69 | if( e_scossl_initialize_rsa_key(rsa, keyCtx) == 0 ) 70 | { 71 | return SCOSSL_UNSUPPORTED; 72 | } 73 | } 74 | 75 | return scossl_rsapss_sign(keyCtx->key, type, cbSalt, tbs, tbslen, sig, (SIZE_T*)siglen); 76 | } 77 | 78 | SCOSSL_STATUS e_scossl_rsapss_verify(_Inout_ EVP_PKEY_CTX *ctx, _In_reads_bytes_(siglen) const unsigned char *sig, size_t siglen, 79 | _In_reads_bytes_(tbslen) const unsigned char *tbs, size_t tbslen) 80 | { 81 | EVP_PKEY* pkey = NULL; 82 | const RSA* rsa = NULL; 83 | SCOSSL_RSA_KEY_CONTEXT *keyCtx = NULL; 84 | const EVP_MD *messageDigest; 85 | const EVP_MD *mgf1Digest; 86 | int type = 0; 87 | int cbSalt = RSA_PSS_SALTLEN_DIGEST; 88 | 89 | if( EVP_PKEY_CTX_get_signature_md(ctx, &messageDigest) <= 0 ) 90 | { 91 | SCOSSL_LOG_ERROR(SCOSSL_ERR_F_ENG_RSAPSS_VERIFY, ERR_R_OPERATION_FAIL, 92 | "Failed to get messageDigest"); 93 | return SCOSSL_UNSUPPORTED; 94 | } 95 | if( EVP_PKEY_CTX_get_rsa_mgf1_md(ctx, &mgf1Digest) <= 0 ) 96 | { 97 | SCOSSL_LOG_ERROR(SCOSSL_ERR_F_ENG_RSAPSS_VERIFY, ERR_R_OPERATION_FAIL, 98 | "Failed to get mgf1Digest"); 99 | return SCOSSL_UNSUPPORTED; 100 | } 101 | type = EVP_MD_type(messageDigest); 102 | 103 | if( type != EVP_MD_type(mgf1Digest) ) 104 | { 105 | SCOSSL_LOG_ERROR(SCOSSL_ERR_F_ENG_RSAPSS_VERIFY, SCOSSL_ERR_R_NOT_IMPLEMENTED, 106 | "messageDigest and mgf1Digest do not match"); 107 | return SCOSSL_UNSUPPORTED; 108 | } 109 | 110 | if( ((pkey = EVP_PKEY_CTX_get0_pkey(ctx)) == NULL) || 111 | ((rsa = EVP_PKEY_get0_RSA(pkey)) == NULL) ) 112 | { 113 | SCOSSL_LOG_ERROR(SCOSSL_ERR_F_ENG_RSAPSS_VERIFY, SCOSSL_ERR_R_MISSING_CTX_DATA, 114 | "Failed to get RSA key from ctx"); 115 | return SCOSSL_UNSUPPORTED; 116 | } 117 | 118 | if( EVP_PKEY_CTX_get_rsa_pss_saltlen(ctx, &cbSalt) <= 0 ) 119 | { 120 | SCOSSL_LOG_ERROR(SCOSSL_ERR_F_ENG_RSAPSS_VERIFY, ERR_R_OPERATION_FAIL, 121 | "Failed to get cbSalt"); 122 | return SCOSSL_UNSUPPORTED; 123 | } 124 | 125 | keyCtx = RSA_get_ex_data(rsa, e_scossl_rsa_idx); 126 | if( keyCtx == NULL ) 127 | { 128 | SCOSSL_LOG_ERROR(SCOSSL_ERR_F_ENG_RSAPSS_VERIFY, SCOSSL_ERR_R_MISSING_CTX_DATA, 129 | "SymCrypt Context Not Found."); 130 | return SCOSSL_FAILURE; 131 | } 132 | if( keyCtx->initialized == 0 ) 133 | { 134 | if( e_scossl_initialize_rsa_key(rsa, keyCtx) == 0 ) 135 | { 136 | return SCOSSL_UNSUPPORTED; 137 | } 138 | } 139 | 140 | if( sig == NULL ) 141 | { 142 | return SCOSSL_FAILURE; 143 | } 144 | 145 | return scossl_rsapss_verify(keyCtx->key, type, cbSalt, tbs, tbslen, sig, siglen); 146 | } 147 | 148 | 149 | #ifdef __cplusplus 150 | } 151 | #endif -------------------------------------------------------------------------------- /SymCryptEngine/src/e_scossl_rsapss.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include "e_scossl.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | // Signs tbs using key in ctx and stores signature and length in sig and siglen. NULL sig can be passed to get the 12 | // length needed for sig, returned in siglen. 13 | // Returns SCOSSL_SUCCESS on success, SCOSSL_FAILURE on failure, or a negative value when the operation is not supported 14 | SCOSSL_STATUS e_scossl_rsapss_sign(_Inout_ EVP_PKEY_CTX *ctx, _Out_writes_opt_(*siglen) unsigned char *sig, _Out_ size_t *siglen, 15 | _In_reads_bytes_(tbslen) const unsigned char *tbs, size_t tbslen); 16 | 17 | // Verifies signature sig for tbs. 18 | // Returns SCOSSL_SUCCESS on success, SCOSSL_FAILURE on failure, or a negative value when the operation is not supported 19 | SCOSSL_STATUS e_scossl_rsapss_verify(_Inout_ EVP_PKEY_CTX *ctx, _In_reads_bytes_(siglen) const unsigned char *sig, size_t siglen, 20 | _In_reads_bytes_(tbslen) const unsigned char *tbs, size_t tbslen); 21 | 22 | #ifdef __cplusplus 23 | } 24 | #endif 25 | -------------------------------------------------------------------------------- /SymCryptEngine/src/e_scossl_sshkdf.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include "e_scossl.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | EVP_KDF_CTX* e_scossl_EVP_KDF_CTX_new_id(int id); 12 | 13 | #ifdef __cplusplus 14 | } 15 | #endif 16 | -------------------------------------------------------------------------------- /SymCryptEngine/src/e_scossl_tls1prf.c: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include "scossl_tls1prf.h" 6 | #include "e_scossl_tls1prf.h" 7 | 8 | #include 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | _Use_decl_annotations_ 15 | SCOSSL_STATUS e_scossl_tls1prf_init(EVP_PKEY_CTX *ctx) 16 | { 17 | SCOSSL_TLS1_PRF_CTX *key_context = NULL; 18 | if ((key_context = scossl_tls1prf_newctx()) == NULL) 19 | { 20 | SCOSSL_LOG_ERROR(SCOSSL_ERR_F_ENG_TLS1PRF_INIT, ERR_R_MALLOC_FAILURE, 21 | "OPENSSL_zalloc return NULL"); 22 | return SCOSSL_FAILURE; 23 | } 24 | EVP_PKEY_CTX_set_data(ctx, key_context); 25 | return SCOSSL_SUCCESS; 26 | } 27 | 28 | _Use_decl_annotations_ 29 | void e_scossl_tls1prf_cleanup(EVP_PKEY_CTX *ctx) 30 | { 31 | SCOSSL_TLS1_PRF_CTX *key_context = (SCOSSL_TLS1_PRF_CTX *)EVP_PKEY_CTX_get_data(ctx); 32 | if (key_context == NULL) 33 | return; 34 | 35 | scossl_tls1prf_freectx(key_context); 36 | 37 | EVP_PKEY_CTX_set_data(ctx, NULL); 38 | } 39 | 40 | _Use_decl_annotations_ 41 | SCOSSL_STATUS e_scossl_tls1prf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) 42 | { 43 | SCOSSL_TLS1_PRF_CTX *key_context = (SCOSSL_TLS1_PRF_CTX *)EVP_PKEY_CTX_get_data(ctx); 44 | PCSYMCRYPT_MAC symcryptHmacAlg = NULL; 45 | BOOL isTlsPrf1_1 = TRUE; 46 | 47 | switch (type) 48 | { 49 | case EVP_PKEY_CTRL_TLS_MD: 50 | // Special case to always allow md5_sha1 for tls1.1 PRF compat 51 | if (EVP_MD_type(p2) != NID_md5_sha1) 52 | { 53 | if ((symcryptHmacAlg = scossl_get_symcrypt_hmac_algorithm(EVP_MD_type(p2))) == NULL) 54 | return SCOSSL_FAILURE; 55 | isTlsPrf1_1 = FALSE; 56 | } 57 | key_context->pHmac = symcryptHmacAlg; 58 | key_context->isTlsPrf1_1 = isTlsPrf1_1; 59 | return SCOSSL_SUCCESS; 60 | case EVP_PKEY_CTRL_TLS_SECRET: 61 | if (p1 < 0) 62 | return SCOSSL_FAILURE; 63 | if (key_context->pbSecret != NULL) 64 | OPENSSL_clear_free(key_context->pbSecret, key_context->cbSecret); 65 | OPENSSL_cleanse(key_context->seed, key_context->cbSeed); 66 | key_context->cbSeed = 0; 67 | key_context->pbSecret = OPENSSL_memdup(p2, p1); 68 | if (key_context->pbSecret == NULL) 69 | return SCOSSL_FAILURE; 70 | key_context->cbSecret = p1; 71 | return SCOSSL_SUCCESS; 72 | case EVP_PKEY_CTRL_TLS_SEED: 73 | if (p1 == 0 || p2 == NULL) 74 | return SCOSSL_SUCCESS; 75 | return scossl_tls1prf_append_seed(key_context, p2, p1); 76 | default: 77 | SCOSSL_LOG_ERROR(SCOSSL_ERR_F_ENG_TLS1PRF_CTRL, SCOSSL_ERR_R_NOT_IMPLEMENTED, 78 | "SymCrypt Engine does not support ctrl type (%d)", type); 79 | return SCOSSL_UNSUPPORTED; 80 | } 81 | } 82 | 83 | _Use_decl_annotations_ 84 | SCOSSL_STATUS e_scossl_tls1prf_derive_init(EVP_PKEY_CTX *ctx) 85 | { 86 | SCOSSL_TLS1_PRF_CTX *key_context = (SCOSSL_TLS1_PRF_CTX *)EVP_PKEY_CTX_get_data(ctx); 87 | return scossl_tls1prf_reset(key_context); 88 | } 89 | 90 | _Use_decl_annotations_ 91 | SCOSSL_STATUS e_scossl_tls1prf_derive(EVP_PKEY_CTX *ctx, 92 | unsigned char *key, size_t *keylen) 93 | { 94 | SCOSSL_TLS1_PRF_CTX *key_context = (SCOSSL_TLS1_PRF_CTX *)EVP_PKEY_CTX_get_data(ctx); 95 | return scossl_tls1prf_derive(key_context, key, *keylen); 96 | } 97 | 98 | #ifdef __cplusplus 99 | } 100 | #endif -------------------------------------------------------------------------------- /SymCryptEngine/src/e_scossl_tls1prf.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include "e_scossl.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | // Allocate SymCrypt context inside of ctx. 12 | // Returns SCOSSL_SUCCESS on success or SCOSSL_FAILURE on error. 13 | SCOSSL_STATUS e_scossl_tls1prf_init(_Inout_ EVP_PKEY_CTX *ctx); 14 | 15 | // Frees SymCrypt context inside of ctx. 16 | void e_scossl_tls1prf_cleanup(_Inout_ EVP_PKEY_CTX *ctx); 17 | 18 | // Sends a control operation to context ctx. type indicates which operation, and 19 | // p1 and p2 are optional parameters depending on which type is used. 20 | // Returns SCOSSL_SUCCESS on success, SCOSSL_FAILURE on error, or SCOSSL_UNSUPPORTED on not supported. 21 | SCOSSL_STATUS e_scossl_tls1prf_ctrl(_Inout_ EVP_PKEY_CTX *ctx, int type, int p1, _In_ void *p2); 22 | 23 | // Initializes context ctx. 24 | // Returns SCOSSL_SUCCESS on success or SCOSSL_FAILURE on error. 25 | SCOSSL_STATUS e_scossl_tls1prf_derive_init(_Inout_ EVP_PKEY_CTX *ctx); 26 | 27 | // Derives a shared secret using ctx. 28 | // NOTE: The documentation states that if the key is NULL, then keylen will be set to the maximum size of 29 | // the output buffer. This is not true for TLS1-PRF, and the keylen is always expected. 30 | // Returns SCOSSL_SUCCESS on success, or SCOSSL_FAILURE on error. 31 | SCOSSL_STATUS e_scossl_tls1prf_derive(_Inout_ EVP_PKEY_CTX *ctx, 32 | _Out_writes_bytes_(*keylen) unsigned char *key, _In_ size_t *keylen); 33 | 34 | #ifdef __cplusplus 35 | } 36 | #endif 37 | -------------------------------------------------------------------------------- /SymCryptEngine/static/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13.0) 2 | 3 | project(scossl_engine_static) 4 | 5 | set(DEFAULT_BUILD_TYPE "Release") 6 | 7 | include(GNUInstallDirs) 8 | 9 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wno-deprecated-declarations -Wno-unused-parameter -Wno-unknown-pragmas") 10 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1y -Wall -Wextra -Wno-deprecated-declarations -Wno-unused-parameter") 11 | 12 | find_package(OpenSSL REQUIRED) 13 | include_directories(${OPENSSL_INCLUDE_DIR}) 14 | 15 | set(SCOSSL_SOURCES 16 | ../src/e_scossl.c 17 | ../src/e_scossl_ciphers.c 18 | ../src/e_scossl_dh.c 19 | ../src/e_scossl_digests.c 20 | ../src/e_scossl_dsa.c 21 | ../src/e_scossl_ecc.c 22 | ../src/e_scossl_rand.c 23 | ../src/e_scossl_rsa.c 24 | ../src/e_scossl_rsapss.c 25 | ../src/e_scossl_hkdf.c 26 | ../src/e_scossl_tls1prf.c 27 | ../src/e_scossl_hmac.c 28 | ) 29 | 30 | if (SCOSSL_SSHKDF) 31 | list(APPEND SCOSSL_SOURCES ../src/e_scossl_sshkdf.c) 32 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DSCOSSL_SSHKDF") 33 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSCOSSL_SSHKDF") 34 | endif() 35 | 36 | if (${OPENSSL_VERSION} VERSION_EQUAL 1) 37 | list(APPEND SCOSSL_SOURCES ../src/e_scossl_pkey_meths.c) 38 | endif() 39 | 40 | add_library(scossl_static STATIC ${SCOSSL_SOURCES}) 41 | add_dependencies(scossl_static scossl_common) 42 | 43 | set_target_properties(scossl_static PROPERTIES PUBLIC_HEADER ../inc/e_scossl.h) 44 | # target_link_libraries(scossl_static ${OPENSSL_CRYPTO_LIBRARY}) 45 | target_include_directories(scossl_static PUBLIC ../inc) 46 | target_include_directories(scossl_static PRIVATE ../src) 47 | target_include_directories(scossl_static PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/..) 48 | target_include_directories(scossl_static PUBLIC ../ScosslCommon/inc) 49 | 50 | target_link_libraries(scossl_static PRIVATE scossl_common) 51 | 52 | install(TARGETS scossl_static 53 | EXCLUDE_FROM_ALL 54 | LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} 55 | PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) 56 | -------------------------------------------------------------------------------- /SymCryptProvider/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13.0) 2 | 3 | project(scossl_provider) 4 | 5 | set(DEFAULT_BUILD_TYPE "Release") 6 | 7 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wno-unknown-pragmas") 8 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1y -Wall -Wextra") 9 | 10 | configure_file( 11 | ${CMAKE_CURRENT_SOURCE_DIR}/inc/p_scossl_base.h.in 12 | ${CMAKE_CURRENT_SOURCE_DIR}/inc/p_scossl_base.h) 13 | 14 | find_package(OpenSSL REQUIRED) 15 | include_directories(${OPENSSL_INCLUDE_DIR}) 16 | 17 | find_library(SYMCRYPT_LIBRARY symcrypt PATHS ${CMAKE_SOURCE_DIR}) 18 | 19 | set(SCOSSL_SOURCES 20 | ./src/asymcipher/p_scossl_rsa_cipher.c 21 | ./src/ciphers/p_scossl_aes.c 22 | ./src/ciphers/p_scossl_aes_aead.c 23 | ./src/ciphers/p_scossl_aes_xts.c 24 | ./src/decoder/p_scossl_decode_common.c 25 | ./src/decoder/p_scossl_decode_mlkem.c 26 | ./src/digests/p_scossl_digest_common.c 27 | ./src/digests/p_scossl_digest_generic.c 28 | ./src/digests/p_scossl_shake.c 29 | ./src/digests/p_scossl_cshake.c 30 | ./src/encoder/p_scossl_encode_common.c 31 | ./src/encoder/p_scossl_encode_mlkem.c 32 | ./src/kdf/p_scossl_hkdf.c 33 | ./src/kdf/p_scossl_kbkdf.c 34 | ./src/kdf/p_scossl_pbkdf2.c 35 | ./src/kdf/p_scossl_srtpkdf.c 36 | ./src/kdf/p_scossl_sshkdf.c 37 | ./src/kdf/p_scossl_sskdf.c 38 | ./src/kdf/p_scossl_tls1prf.c 39 | ./src/kem/p_scossl_mlkem.c 40 | ./src/keyexch/p_scossl_dh.c 41 | ./src/keyexch/p_scossl_ecdh.c 42 | ./src/keyexch/p_scossl_kdf_keyexch.c 43 | ./src/keymgmt/p_scossl_dh_keymgmt.c 44 | ./src/keymgmt/p_scossl_ecc_keymgmt.c 45 | ./src/keymgmt/p_scossl_kdf_keymgmt.c 46 | ./src/keymgmt/p_scossl_mlkem_keymgmt.c 47 | ./src/keymgmt/p_scossl_rsa_keymgmt.c 48 | ./src/mac/p_scossl_cmac.c 49 | ./src/mac/p_scossl_hmac.c 50 | ./src/mac/p_scossl_kmac.c 51 | ./src/signature/p_scossl_ecdsa_signature.c 52 | ./src/signature/p_scossl_rsa_signature.c 53 | ./src/p_scossl_bio.c 54 | ./src/p_scossl_ecc.c 55 | ./src/p_scossl_rand.c 56 | ./src/p_scossl_rsa.c 57 | ./src/p_scossl_base.c 58 | ) 59 | 60 | if (KEYSINUSE_ENABLED) 61 | list(APPEND SCOSSL_SOURCES ./src/p_scossl_keysinuse.c) 62 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DKEYSINUSE_ENABLED") 63 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DKEYSINUSE_ENABLED") 64 | endif() 65 | 66 | add_library(scossl_provider SHARED ${SCOSSL_SOURCES}) 67 | add_dependencies(scossl_provider scossl_common) 68 | 69 | set_target_properties(scossl_provider PROPERTIES PUBLIC_HEADER ./inc/p_scossl_base.h) 70 | target_include_directories(scossl_provider PUBLIC ./inc) 71 | target_include_directories(scossl_provider PRIVATE ./src) 72 | # target_include_directories(scossl_provider PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) 73 | target_include_directories(scossl_provider PUBLIC ../ScosslCommon/inc) 74 | 75 | # Remove default "lib" prefix from symcryptprovider.so as OpenSSL provider is not a generic Linux .so 76 | set_target_properties(scossl_provider PROPERTIES PREFIX "") 77 | set_target_properties(scossl_provider PROPERTIES OUTPUT_NAME "symcryptprovider") 78 | 79 | target_link_libraries(scossl_provider PRIVATE scossl_common) 80 | target_link_libraries(scossl_provider PUBLIC ${SYMCRYPT_LIBRARY}) 81 | target_link_libraries(scossl_provider PUBLIC ${OPENSSL_CRYPTO_LIBRARY}) 82 | 83 | if (NOT DEFINED OPENSSL_PROVIDERS) 84 | set(OPENSSL_PROVIDERS "${CMAKE_INSTALL_LIBDIR}/ossl-modules" CACHE PATH "Path to OpenSSL providers") 85 | endif() 86 | 87 | # Install the engine to the OpenSSL modules directory 88 | # NB: this won't work if the distro has a custom modules directory that doesn't match 89 | # the OpenSSL default. 90 | install( 91 | TARGETS scossl_provider 92 | LIBRARY DESTINATION "${OPENSSL_PROVIDERS}" 93 | PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) 94 | -------------------------------------------------------------------------------- /SymCryptProvider/inc/p_scossl_base.h.in: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #pragma once 6 | 7 | #include "scossl_helpers.h" 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #ifdef __cplusplus 14 | extern "C" { 15 | #endif 16 | 17 | // Value provided by CMake, defined in top level CMakeLists.txt 18 | #define P_SCOSSL_VERSION "@SymCrypt-OpenSSL_VERSION@" 19 | #define P_SCOSSL_NAME "symcryptprovider" 20 | #define P_SCOSSL_SYMCRYPT_MINIMUM_MAJOR @SYMCRYPT_MINIMUM_MAJOR@ 21 | #define P_SCOSSL_SYMCRYPT_MINIMUM_MINOR @SYMCRYPT_MINIMUM_MINOR@ 22 | 23 | typedef struct 24 | { 25 | OSSL_LIB_CTX *libctx; 26 | const OSSL_CORE_HANDLE *handle; 27 | BIO_METHOD *coreBioMeth; 28 | } SCOSSL_PROVCTX; 29 | 30 | static const OSSL_PARAM p_scossl_param_types[] = { 31 | OSSL_PARAM_utf8_ptr(OSSL_PROV_PARAM_NAME, NULL, 0), 32 | OSSL_PARAM_utf8_ptr(OSSL_PROV_PARAM_VERSION, NULL, 0), 33 | OSSL_PARAM_utf8_ptr(OSSL_PROV_PARAM_BUILDINFO, NULL, 0), 34 | OSSL_PARAM_int(OSSL_PROV_PARAM_STATUS, NULL), 35 | OSSL_PARAM_END}; 36 | 37 | // EVP_MD_CTX_dup is a helpful function for the provider, but was not added until OpenSSL 3.1 38 | // This function is copied from 3.1 to allow its use when the provider is built against 3.0 39 | #if OPENSSL_VERSION_MAJOR == 3 && OPENSSL_VERSION_MINOR == 0 40 | EVP_MD_CTX *EVP_MD_CTX_dup(const EVP_MD_CTX *in); 41 | 42 | #endif // OPENSSL_VERSION_MAJOR == 3 && OPENSSL_VERSION_MINOR == 0 43 | 44 | #ifdef __cplusplus 45 | } 46 | #endif -------------------------------------------------------------------------------- /SymCryptProvider/inc/scossl_provider.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | // This file contains parameter names and definitions that are not 6 | // part of the default OpenSSL implementation, or belong to an 7 | // algorithm not found in the default OpenSSL implementation, 8 | // but are used by the SymCrypt provider. 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | // 15 | // Digest parameters 16 | // 17 | #define SCOSSL_DIGEST_PARAM_FUNCTION_NAME_STRING "function-name-string" 18 | #define SCOSSL_DIGEST_PARAM_CUSTOMIZATION_STRING "customization-string" 19 | 20 | // 21 | // KDF parameters 22 | // 23 | #define SCOSSL_KDF_PARAM_SRTP_RATE "rate" 24 | #define SCOSSL_KDF_PARAM_SRTP_INDEX "index" 25 | #define SCOSSL_KDF_PARAM_SRTP_INDEX_WIDTH "index-width" 26 | 27 | // 28 | // SRTP labels 29 | // 30 | #define SCOSSL_SRTP_LABEL_ENCRYPTION "encryption" 31 | #define SCOSSL_SRTP_LABEL_AUTHENTICATION "authentication" 32 | #define SCOSSL_SRTP_LABEL_SALTING "salting" 33 | 34 | // 35 | // Extended algorithms not found in default OpenSSL implementation 36 | // 37 | #define SCOSSL_SN_MLKEM512 "id-alg-ml-kem-512" 38 | #define SCOSSL_LN_MLKEM512 "ML-KEM-512" 39 | #define SCOSSL_OID_MLKEM512 "2.16.840.1.101.3.4.4.1" 40 | 41 | #define SCOSSL_SN_MLKEM768 "id-alg-ml-kem-768" 42 | #define SCOSSL_LN_MLKEM768 "ML-KEM-768" 43 | #define SCOSSL_OID_MLKEM768 "2.16.840.1.101.3.4.4.2" 44 | 45 | #define SCOSSL_SN_MLKEM1024 "id-alg-ml-kem-1024" 46 | #define SCOSSL_LN_MLKEM1024 "ML-KEM-1024" 47 | #define SCOSSL_OID_MLKEM1024 "2.16.840.1.101.3.4.4.3" 48 | 49 | #define SCOSSL_SN_P256_MLKEM768 "id-alg-secp256r1-ml-kem-768" 50 | #define SCOSSL_LN_P256_MLKEM768 "P256-ML-KEM-768" 51 | #define SCOSSL_OID_P256_MLKEM768 "2.16.840.1.101.3.4.4.4" 52 | 53 | #define SCOSSL_SN_X25519_MLKEM768 "id-alg-x25519-ml-kem-768" 54 | #define SCOSSL_LN_X25519_MLKEM768 "X25519-ML-KEM-768" 55 | #define SCOSSL_OID_X25519_MLKEM768 "2.16.840.1.101.3.4.4.5" 56 | 57 | #define SCOSSL_SN_P384_MLKEM1024 "id-alg-secp384r1-ml-kem-1024" 58 | #define SCOSSL_LN_P384_MLKEM1024 "P384-ML-KEM-1024" 59 | #define SCOSSL_OID_P384_MLKEM1024 "2.16.840.1.101.3.4.4.6" 60 | 61 | #ifdef __cplusplus 62 | } 63 | #endif -------------------------------------------------------------------------------- /SymCryptProvider/src/ciphers/p_scossl_aes.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | #define SCOSSL_FLAG_AEAD 0x01 10 | #define SCOSSL_FLAG_CUSTOM_IV 0x02 11 | 12 | const OSSL_PARAM *p_scossl_aes_generic_gettable_params(ossl_unused void *provctx); 13 | SCOSSL_STATUS p_scossl_aes_generic_get_params(_Inout_ OSSL_PARAM params[], 14 | unsigned int mode, 15 | size_t keylen, 16 | size_t ivlen, 17 | size_t block_size, 18 | unsigned int flags); 19 | 20 | #ifdef __cplusplus 21 | } 22 | #endif -------------------------------------------------------------------------------- /SymCryptProvider/src/decoder/p_scossl_decode_common.c: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include "p_scossl_bio.h" 6 | #include "p_scossl_decode_common.h" 7 | 8 | #include 9 | #include 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | ASN1_NDEF_SEQUENCE(SUBJECT_PUBKEY_INFO) = { 16 | ASN1_SIMPLE(SUBJECT_PUBKEY_INFO, x509Alg, X509_ALGOR), 17 | ASN1_SIMPLE(SUBJECT_PUBKEY_INFO, subjectPublicKey, ASN1_BIT_STRING), 18 | } ASN1_SEQUENCE_END(SUBJECT_PUBKEY_INFO) 19 | 20 | IMPLEMENT_ASN1_FUNCTIONS(SUBJECT_PUBKEY_INFO) 21 | 22 | const OSSL_PARAM p_scossl_der_to_key_settable_param_types[] = { 23 | OSSL_PARAM_END}; 24 | 25 | _Use_decl_annotations_ 26 | SCOSSL_DECODE_CTX *p_scossl_decode_newctx(SCOSSL_PROVCTX *provctx, const SCOSSL_DECODE_KEYTYPE_DESC *desc) 27 | { 28 | SCOSSL_DECODE_CTX *ctx = OPENSSL_zalloc(sizeof(SCOSSL_DECODE_CTX)); 29 | 30 | if (ctx != NULL) 31 | { 32 | ctx->provctx = provctx; 33 | ctx->desc = desc; 34 | } 35 | 36 | return ctx; 37 | } 38 | 39 | _Use_decl_annotations_ 40 | void p_scossl_decode_freectx(SCOSSL_DECODE_CTX *ctx) 41 | { 42 | if (ctx == NULL) 43 | return; 44 | 45 | OPENSSL_free(ctx); 46 | } 47 | 48 | SCOSSL_STATUS p_scossl_decode_set_ctx_params(ossl_unused void *ctx, ossl_unused const OSSL_PARAM params[]) 49 | { 50 | return SCOSSL_SUCCESS; 51 | } 52 | 53 | const OSSL_PARAM *p_scossl_decode_settable_ctx_params(ossl_unused void *ctx) 54 | { 55 | return p_scossl_der_to_key_settable_param_types; 56 | } 57 | 58 | _Use_decl_annotations_ 59 | BOOL p_scossl_decode_does_selection(const SCOSSL_DECODE_KEYTYPE_DESC *desc, int selection) 60 | { 61 | if (selection == 0) 62 | { 63 | return TRUE; 64 | } 65 | 66 | // Supporting private key implies supporting public key. 67 | // Both imply supporting key parameters 68 | return ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0 && (desc->selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) || 69 | ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0 && (desc->selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) || 70 | ((selection & OSSL_KEYMGMT_SELECT_ALL_PARAMETERS) != 0 && (desc->selection & OSSL_KEYMGMT_SELECT_ALL_PARAMETERS) != 0); 71 | } 72 | 73 | // This function should return SCOSSL_SUCCESS if it successfully decodes something, 74 | // or decodes nothing at all. Another decoder may be able to decode the data into something. 75 | // This function should only return SCOSSL_FAILURE if the data could be decoded, but further 76 | // validation of the data failed in a way that another decoder could not handle. 77 | _Use_decl_annotations_ 78 | SCOSSL_STATUS p_scossl_decode(SCOSSL_DECODE_CTX *ctx, OSSL_CORE_BIO *in, int selection, 79 | OSSL_CALLBACK *dataCb, void *dataCbArg, 80 | ossl_unused OSSL_PASSPHRASE_CALLBACK *passphraseCb, ossl_unused void *passphraseCbArg) 81 | { 82 | BIO *bio = NULL; 83 | PVOID *keyCtx = NULL; 84 | OSSL_PARAM cbParams[4]; 85 | SCOSSL_STATUS ret = SCOSSL_SUCCESS; 86 | 87 | if (selection == 0) 88 | { 89 | selection = ctx->desc->selection; 90 | } 91 | 92 | if ((selection & ctx->desc->selection) != 0 && 93 | (bio = p_scossl_bio_new_from_core_bio(ctx->provctx, in)) != NULL) 94 | { 95 | keyCtx = ctx->desc->decodeInternal(ctx, bio); 96 | } 97 | 98 | if (keyCtx != NULL) 99 | { 100 | int objectType = OSSL_OBJECT_PKEY; 101 | 102 | cbParams[0] = OSSL_PARAM_construct_int(OSSL_OBJECT_PARAM_TYPE, &objectType); 103 | cbParams[1] = OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_TYPE, (char *)ctx->desc->dataType, 0); 104 | cbParams[2] = OSSL_PARAM_construct_octet_string(OSSL_OBJECT_PARAM_REFERENCE, &keyCtx, sizeof(keyCtx)); 105 | cbParams[3] = OSSL_PARAM_construct_end(); 106 | 107 | ret = dataCb(cbParams, dataCbArg); 108 | } 109 | 110 | ctx->desc->freeKeyCtx(keyCtx); 111 | BIO_free(bio); 112 | 113 | return ret; 114 | } 115 | 116 | const ASN1_ITEM *p_scossl_decode_subject_pubkey_asn1_item() 117 | { 118 | return ASN1_ITEM_rptr(SUBJECT_PUBKEY_INFO); 119 | } 120 | 121 | #ifdef __cplusplus 122 | } 123 | #endif -------------------------------------------------------------------------------- /SymCryptProvider/src/decoder/p_scossl_decode_common.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include "p_scossl_base.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #define select_PrivateKeyInfo OSSL_KEYMGMT_SELECT_PRIVATE_KEY 12 | #define select_SubjectPublicKeyInfo OSSL_KEYMGMT_SELECT_PUBLIC_KEY 13 | 14 | typedef PVOID (*PSCOSSL_DECODE_INTERNAL_FN) (_In_ PVOID decodeCtx, _In_ BIO *bio); 15 | 16 | typedef struct 17 | { 18 | const char *dataType; 19 | int selection; 20 | 21 | PSCOSSL_DECODE_INTERNAL_FN decodeInternal; 22 | OSSL_FUNC_keymgmt_free_fn *freeKeyCtx; 23 | } SCOSSL_DECODE_KEYTYPE_DESC; 24 | 25 | typedef struct scossl_decode_ctx_st 26 | { 27 | SCOSSL_PROVCTX *provctx; 28 | 29 | const SCOSSL_DECODE_KEYTYPE_DESC *desc; 30 | } SCOSSL_DECODE_CTX; 31 | 32 | typedef struct 33 | { 34 | X509_ALGOR *x509Alg; 35 | ASN1_BIT_STRING *subjectPublicKey; 36 | } SUBJECT_PUBKEY_INFO; 37 | 38 | SCOSSL_DECODE_CTX *p_scossl_decode_newctx(_In_ SCOSSL_PROVCTX *provctx, _In_ const SCOSSL_DECODE_KEYTYPE_DESC *desc); 39 | void p_scossl_decode_freectx(_Inout_ SCOSSL_DECODE_CTX *ctx); 40 | 41 | SCOSSL_STATUS p_scossl_decode_set_ctx_params(ossl_unused void *ctx, ossl_unused const OSSL_PARAM params[]); 42 | const OSSL_PARAM *p_scossl_decode_settable_ctx_params(ossl_unused void *ctx); 43 | 44 | BOOL p_scossl_decode_does_selection(_In_ const SCOSSL_DECODE_KEYTYPE_DESC *desc, int selection); 45 | 46 | SCOSSL_STATUS p_scossl_decode(_In_ SCOSSL_DECODE_CTX *ctx, _In_ OSSL_CORE_BIO *in, 47 | int selection, 48 | _In_ OSSL_CALLBACK *dataCb, _In_ void *dataCbArg, 49 | ossl_unused OSSL_PASSPHRASE_CALLBACK *passphraseCb, ossl_unused void *passphraseCbArg); 50 | 51 | const ASN1_ITEM *p_scossl_decode_subject_pubkey_asn1_item(); 52 | 53 | #ifdef __cplusplus 54 | } 55 | #endif -------------------------------------------------------------------------------- /SymCryptProvider/src/digests/p_scossl_digest_common.c: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #include "digests/p_scossl_digest_common.h" 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | const OSSL_PARAM p_scossl_digest_gettable_param_types[] = { 16 | OSSL_PARAM_size_t(OSSL_DIGEST_PARAM_BLOCK_SIZE, NULL), 17 | OSSL_PARAM_size_t(OSSL_DIGEST_PARAM_SIZE, NULL), 18 | OSSL_PARAM_int(OSSL_DIGEST_PARAM_XOF, NULL), 19 | OSSL_PARAM_int(OSSL_DIGEST_PARAM_ALGID_ABSENT, NULL), 20 | OSSL_PARAM_END}; 21 | 22 | _Use_decl_annotations_ 23 | void p_scossl_digest_freectx(SCOSSL_DIGEST_CTX *ctx) 24 | { 25 | if (ctx == NULL) 26 | return; 27 | 28 | if (ctx->pState != NULL) 29 | { 30 | SCOSSL_COMMON_ALIGNED_FREE_EX(ctx->pState, OPENSSL_clear_free, SymCryptHashStateSize(ctx->pHash)); 31 | } 32 | 33 | OPENSSL_free(ctx); 34 | } 35 | 36 | _Use_decl_annotations_ 37 | SCOSSL_DIGEST_CTX *p_scossl_digest_dupctx(SCOSSL_DIGEST_CTX *ctx) 38 | { 39 | SCOSSL_DIGEST_CTX *copyCtx = OPENSSL_malloc(sizeof(SCOSSL_DIGEST_CTX)); 40 | 41 | if (copyCtx != NULL) 42 | { 43 | SCOSSL_COMMON_ALIGNED_ALLOC_EX(pStateTmp, OPENSSL_malloc, PVOID, SymCryptHashStateSize(ctx->pHash)); 44 | if (pStateTmp == NULL) 45 | { 46 | OPENSSL_free(copyCtx); 47 | return NULL; 48 | } 49 | 50 | ctx->pHash->stateCopyFunc(ctx->pState, pStateTmp); 51 | copyCtx->pState = pStateTmp; 52 | 53 | copyCtx->pHash = ctx->pHash; 54 | copyCtx->xofLen = ctx->xofLen; 55 | } 56 | 57 | return copyCtx; 58 | } 59 | 60 | _Use_decl_annotations_ 61 | SCOSSL_STATUS p_scossl_digest_get_params(OSSL_PARAM params[], size_t size, size_t blocksize, UINT32 flags) 62 | { 63 | OSSL_PARAM *p; 64 | 65 | if ((p = OSSL_PARAM_locate(params, OSSL_DIGEST_PARAM_SIZE)) != NULL && 66 | !OSSL_PARAM_set_size_t(p, size)) 67 | { 68 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); 69 | return SCOSSL_FAILURE; 70 | } 71 | 72 | if ((p = OSSL_PARAM_locate(params, OSSL_DIGEST_PARAM_BLOCK_SIZE)) != NULL && 73 | !OSSL_PARAM_set_size_t(p, blocksize)) 74 | { 75 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); 76 | return SCOSSL_FAILURE; 77 | } 78 | 79 | if ((p = OSSL_PARAM_locate(params, OSSL_DIGEST_PARAM_XOF)) != NULL && 80 | !OSSL_PARAM_set_int(p, (flags & SCOSSL_DIGEST_FLAG_XOF) != 0)) 81 | { 82 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); 83 | return SCOSSL_FAILURE; 84 | } 85 | 86 | if ((p = OSSL_PARAM_locate(params, OSSL_DIGEST_PARAM_ALGID_ABSENT)) != NULL && 87 | !OSSL_PARAM_set_int(p, (flags & SCOSSL_DIGEST_FLAG_ALGID_ABSENT) != 0)) 88 | { 89 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); 90 | return SCOSSL_FAILURE; 91 | } 92 | 93 | return SCOSSL_SUCCESS; 94 | } 95 | 96 | const OSSL_PARAM *p_scossl_digest_gettable_params(ossl_unused void *ctx, ossl_unused void *provctx) 97 | { 98 | return p_scossl_digest_gettable_param_types; 99 | } 100 | 101 | _Use_decl_annotations_ 102 | SCOSSL_STATUS p_scossl_digest_update(SCOSSL_DIGEST_CTX *ctx, 103 | const unsigned char *in, size_t inl) 104 | { 105 | SymCryptHashAppend(ctx->pHash, ctx->pState, in, inl); 106 | return SCOSSL_SUCCESS; 107 | } 108 | 109 | _Use_decl_annotations_ 110 | SCOSSL_STATUS p_scossl_digest_digest(PCSYMCRYPT_HASH pHash, 111 | const unsigned char *in, size_t inl, 112 | unsigned char *out, size_t *outl, size_t outlen) 113 | { 114 | SIZE_T cbResult = SymCryptHashResultSize(pHash); 115 | 116 | if (outlen < cbResult) 117 | { 118 | ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); 119 | return SCOSSL_FAILURE; 120 | } 121 | 122 | SymCryptHash(pHash, in, inl, out, cbResult); 123 | *outl = cbResult; 124 | 125 | return SCOSSL_SUCCESS; 126 | } -------------------------------------------------------------------------------- /SymCryptProvider/src/digests/p_scossl_digest_common.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include "scossl_helpers.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #define SCOSSL_DIGEST_FLAG_XOF 0x1 12 | #define SCOSSL_DIGEST_FLAG_ALGID_ABSENT 0x2 13 | 14 | typedef VOID (SYMCRYPT_CALL * PSYMCRYPT_HASH_EXTRACT) (PVOID pState, PBYTE pbResult, SIZE_T cbResult, BOOLEAN bWipe); 15 | 16 | typedef struct 17 | { 18 | PCSYMCRYPT_HASH pHash; 19 | PVOID pState; 20 | 21 | SIZE_T xofLen; 22 | } SCOSSL_DIGEST_CTX; 23 | 24 | SCOSSL_DIGEST_CTX *p_scossl_digest_dupctx(_In_ SCOSSL_DIGEST_CTX *ctx); 25 | void p_scossl_digest_freectx(_Inout_ SCOSSL_DIGEST_CTX *ctx); 26 | 27 | SCOSSL_STATUS p_scossl_digest_update(_Inout_ SCOSSL_DIGEST_CTX *ctx, 28 | _In_reads_bytes_(inl) const unsigned char *in, size_t inl); 29 | SCOSSL_STATUS p_scossl_digest_digest(_In_ PCSYMCRYPT_HASH pHash, 30 | _In_reads_bytes_(inl) const unsigned char *in, size_t inl, 31 | _Out_writes_bytes_(*outl) unsigned char *out, _Out_ size_t *outl, size_t outlen); 32 | 33 | SCOSSL_STATUS p_scossl_digest_get_params(_Inout_ OSSL_PARAM params[], size_t size, size_t blocksize, UINT32 flags); 34 | const OSSL_PARAM *p_scossl_digest_gettable_params(ossl_unused void *ctx, ossl_unused void *provctx); 35 | 36 | #define SCOSSL_DIGEST_FUNCTIONS_COMMON(alg, dispatch_name, flags) \ 37 | static SCOSSL_DIGEST_CTX *p_scossl_##dispatch_name##_newctx(ossl_unused void *prov_ctx) \ 38 | { \ 39 | SCOSSL_DIGEST_CTX *ctx = OPENSSL_malloc(sizeof(SCOSSL_DIGEST_CTX)); \ 40 | \ 41 | if (ctx != NULL) \ 42 | { \ 43 | ctx->pHash = SymCrypt##alg##Algorithm; \ 44 | \ 45 | SCOSSL_COMMON_ALIGNED_ALLOC_EX( \ 46 | pStateTmp, \ 47 | OPENSSL_malloc, \ 48 | PVOID, \ 49 | SymCryptHashStateSize(ctx->pHash)); \ 50 | if (pStateTmp == NULL) \ 51 | { \ 52 | OPENSSL_free(ctx); \ 53 | return NULL; \ 54 | } \ 55 | \ 56 | ctx->pState = pStateTmp; \ 57 | } \ 58 | \ 59 | return ctx; \ 60 | } \ 61 | \ 62 | static SCOSSL_STATUS p_scossl_##dispatch_name##_digest( \ 63 | ossl_unused void *prov_ctx, \ 64 | _In_reads_bytes_(inl) const unsigned char *in, size_t inl, \ 65 | _Out_writes_bytes_(*outl) unsigned char *out, _Out_ size_t *outl, size_t outlen) \ 66 | { \ 67 | return p_scossl_digest_digest(SymCrypt##alg##Algorithm, in, inl, out, outl, outlen); \ 68 | } \ 69 | \ 70 | static SCOSSL_STATUS p_scossl_##dispatch_name##_get_params(_Inout_ OSSL_PARAM params[]) \ 71 | { \ 72 | return p_scossl_digest_get_params( \ 73 | params, \ 74 | SymCryptHashResultSize(SymCrypt##alg##Algorithm), \ 75 | SymCryptHashInputBlockSize(SymCrypt##alg##Algorithm), \ 76 | flags); \ 77 | } \ 78 | \ 79 | const OSSL_DISPATCH p_scossl_##dispatch_name##_functions[] = { \ 80 | {OSSL_FUNC_DIGEST_NEWCTX, (void (*)(void))p_scossl_##dispatch_name##_newctx}, \ 81 | {OSSL_FUNC_DIGEST_FREECTX, (void (*)(void))p_scossl_digest_freectx}, \ 82 | {OSSL_FUNC_DIGEST_DUPCTX, (void (*)(void))p_scossl_digest_dupctx}, \ 83 | {OSSL_FUNC_DIGEST_GET_PARAMS, (void (*)(void))p_scossl_##dispatch_name##_get_params}, \ 84 | {OSSL_FUNC_DIGEST_GETTABLE_PARAMS, (void (*)(void))p_scossl_digest_gettable_params}, \ 85 | {OSSL_FUNC_DIGEST_UPDATE, (void (*)(void))p_scossl_digest_update}, \ 86 | {OSSL_FUNC_DIGEST_DIGEST, (void (*)(void))p_scossl_##dispatch_name##_digest}, 87 | 88 | #define SCOSSL_DIGEST_FUNCTIONS_END \ 89 | {0, NULL}}; 90 | 91 | #ifdef __cplusplus 92 | } 93 | #endif -------------------------------------------------------------------------------- /SymCryptProvider/src/digests/p_scossl_shake.c: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include 6 | #include 7 | 8 | #include "digests/p_scossl_digest_common.h" 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | static const OSSL_PARAM p_scossl_shake_settable_ctx_param_types[] = { 15 | OSSL_PARAM_size_t(OSSL_DIGEST_PARAM_XOFLEN, NULL), 16 | OSSL_PARAM_END}; 17 | 18 | static SCOSSL_STATUS p_scossl_shake_set_ctx_params(_Inout_ SCOSSL_DIGEST_CTX *ctx, _In_ const OSSL_PARAM params[]) 19 | { 20 | const OSSL_PARAM *p; 21 | 22 | if ((p = OSSL_PARAM_locate_const(params, OSSL_DIGEST_PARAM_XOFLEN)) != NULL && 23 | !OSSL_PARAM_get_size_t(p, &ctx->xofLen)) 24 | { 25 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); 26 | return SCOSSL_FAILURE; 27 | } 28 | 29 | return SCOSSL_SUCCESS; 30 | } 31 | 32 | static const OSSL_PARAM *p_scossl_shake_settable_ctx_params(ossl_unused void *ctx, ossl_unused void *provctx) 33 | { 34 | return p_scossl_shake_settable_ctx_param_types; 35 | } 36 | 37 | static SCOSSL_STATUS p_scossl_shake_init(_Inout_ SCOSSL_DIGEST_CTX *ctx, ossl_unused const OSSL_PARAM params[]) 38 | { 39 | SymCryptHashInit(ctx->pHash, ctx->pState); 40 | ctx->xofLen = SymCryptHashResultSize(ctx->pHash); 41 | 42 | return p_scossl_shake_set_ctx_params(ctx, params); 43 | } 44 | 45 | static SCOSSL_STATUS p_scossl_shake_extract(_Inout_ SCOSSL_DIGEST_CTX *ctx, 46 | PSYMCRYPT_HASH_EXTRACT extractFunc, BOOLEAN wipeState, 47 | _Out_writes_bytes_(*outl) unsigned char *out, _Out_ size_t *outl, size_t outlen) 48 | { 49 | extractFunc(ctx->pState, out, outlen, wipeState); 50 | *outl = outlen; 51 | 52 | return SCOSSL_SUCCESS; 53 | } 54 | 55 | #ifdef OSSL_FUNC_DIGEST_SQUEEZE 56 | #define SCOSSL_DIGEST_SHAKE_SQUEEZE(bits) \ 57 | {OSSL_FUNC_DIGEST_SQUEEZE, (void (*)(void))p_scossl_shake_##bits##_squeeze}, 58 | #else 59 | #define SCOSSL_DIGEST_SHAKE_SQUEEZE(bits) 60 | #endif 61 | 62 | #define IMPLEMENT_SCOSSL_SHAKE(bits) \ 63 | static SCOSSL_STATUS p_scossl_shake_##bits##_final( \ 64 | _In_ SCOSSL_DIGEST_CTX *ctx, \ 65 | _Out_writes_bytes_(*outl) unsigned char *out, _Out_ size_t *outl, size_t outlen) \ 66 | { \ 67 | if (outlen < ctx->xofLen) \ 68 | { \ 69 | ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); \ 70 | return SCOSSL_FAILURE; \ 71 | } \ 72 | \ 73 | return p_scossl_shake_extract(ctx, \ 74 | (PSYMCRYPT_HASH_EXTRACT)SymCryptShake##bits##Extract, \ 75 | TRUE, \ 76 | out, outl, ctx->xofLen); \ 77 | } \ 78 | \ 79 | static SCOSSL_STATUS p_scossl_shake_##bits##_squeeze( \ 80 | _In_ SCOSSL_DIGEST_CTX *ctx, \ 81 | _Out_writes_bytes_(*outl) unsigned char *out, _Out_ size_t *outl, size_t outlen) \ 82 | { \ 83 | return p_scossl_shake_extract(ctx, \ 84 | (PSYMCRYPT_HASH_EXTRACT)SymCryptShake##bits##Extract, \ 85 | FALSE, \ 86 | out, outl, outlen); \ 87 | } \ 88 | \ 89 | SCOSSL_DIGEST_FUNCTIONS_COMMON(Shake##bits##Hash, shake_##bits, SCOSSL_DIGEST_FLAG_XOF) \ 90 | {OSSL_FUNC_DIGEST_SET_CTX_PARAMS, (void (*)(void))p_scossl_shake_set_ctx_params}, \ 91 | {OSSL_FUNC_DIGEST_SETTABLE_CTX_PARAMS, (void (*)(void))p_scossl_shake_settable_ctx_params}, \ 92 | {OSSL_FUNC_DIGEST_INIT, (void (*)(void))p_scossl_shake_init}, \ 93 | {OSSL_FUNC_DIGEST_FINAL, (void (*)(void))p_scossl_shake_##bits##_final}, \ 94 | SCOSSL_DIGEST_SHAKE_SQUEEZE(bits) \ 95 | SCOSSL_DIGEST_FUNCTIONS_END 96 | 97 | //SHAKE 98 | IMPLEMENT_SCOSSL_SHAKE(128) 99 | IMPLEMENT_SCOSSL_SHAKE(256) 100 | 101 | #ifdef __cplusplus 102 | } 103 | #endif -------------------------------------------------------------------------------- /SymCryptProvider/src/encoder/p_scossl_encode_common.c: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include "p_scossl_bio.h" 6 | #include "p_scossl_encode_common.h" 7 | 8 | #include 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | #define KEY_TO_TEXT_PRINT_WIDTH 15 15 | 16 | static const OSSL_PARAM p_scossl_encode_settable_param_types[] = { 17 | OSSL_PARAM_utf8_string(OSSL_ENCODER_PARAM_CIPHER, NULL, 0), 18 | OSSL_PARAM_utf8_string(OSSL_ENCODER_PARAM_PROPERTIES, NULL, 0), 19 | OSSL_PARAM_END}; 20 | 21 | _Use_decl_annotations_ 22 | SCOSSL_ENCODE_CTX *p_scossl_encode_newctx(SCOSSL_PROVCTX *provctx, const SCOSSL_ENCODE_KEYTYPE_DESC *desc) 23 | { 24 | SCOSSL_ENCODE_CTX *ctx = OPENSSL_zalloc(sizeof(SCOSSL_ENCODE_CTX)); 25 | 26 | if (ctx != NULL) 27 | { 28 | ctx->provctx = provctx; 29 | ctx->desc = desc; 30 | } 31 | 32 | return ctx; 33 | } 34 | 35 | _Use_decl_annotations_ 36 | void p_scossl_encode_freectx(SCOSSL_ENCODE_CTX *ctx) 37 | { 38 | if (ctx == NULL) 39 | return; 40 | 41 | OPENSSL_free(ctx); 42 | } 43 | 44 | _Use_decl_annotations_ 45 | SCOSSL_STATUS p_scossl_encode_set_ctx_params(SCOSSL_ENCODE_CTX *ctx, const OSSL_PARAM params[]) 46 | { 47 | const OSSL_PARAM *p; 48 | 49 | if ((p = OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_CIPHER)) != NULL) 50 | { 51 | OSSL_LIB_CTX *libctx = ctx->provctx == NULL ? NULL : ctx->provctx->libctx; 52 | const char *cipherName = NULL; 53 | const char *propQ = NULL; 54 | 55 | if (!OSSL_PARAM_get_utf8_string_ptr(p, &cipherName)) 56 | { 57 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); 58 | return SCOSSL_FAILURE; 59 | } 60 | 61 | if ((p = OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_PROPERTIES)) != NULL && 62 | !OSSL_PARAM_get_utf8_string_ptr(p, &propQ)) 63 | { 64 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); 65 | return SCOSSL_FAILURE; 66 | } 67 | 68 | EVP_CIPHER_free(ctx->cipher); 69 | 70 | if (cipherName != NULL) 71 | { 72 | if ((ctx->cipher = EVP_CIPHER_fetch(libctx, cipherName, propQ)) == NULL) 73 | { 74 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); 75 | return SCOSSL_FAILURE; 76 | } 77 | } 78 | else 79 | { 80 | ctx->cipher = NULL; 81 | } 82 | } 83 | 84 | return SCOSSL_SUCCESS; 85 | } 86 | 87 | const OSSL_PARAM *p_scossl_encode_settable_ctx_params(ossl_unused void *provctx) 88 | { 89 | return p_scossl_encode_settable_param_types; 90 | } 91 | 92 | BOOL p_scossl_encode_does_selection(const SCOSSL_ENCODE_KEYTYPE_DESC *desc, int selection) 93 | { 94 | if (selection == 0) 95 | { 96 | return TRUE; 97 | } 98 | 99 | // Supporting private key implies supporting public key. 100 | // Both imply supporting key parameters 101 | return ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0 && (desc->selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) || 102 | ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0 && (desc->selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) || 103 | ((selection & OSSL_KEYMGMT_SELECT_ALL_PARAMETERS) != 0 && (desc->selection & OSSL_KEYMGMT_SELECT_ALL_PARAMETERS) != 0); 104 | } 105 | 106 | _Use_decl_annotations_ 107 | SCOSSL_STATUS p_scossl_encode(SCOSSL_ENCODE_CTX *ctx, OSSL_CORE_BIO *out, 108 | const void *keyCtx, 109 | const OSSL_PARAM keyAbstract[], 110 | int selection, 111 | OSSL_PASSPHRASE_CALLBACK *passphraseCb, void *passphraseCbArgs) 112 | { 113 | BIO *bio = NULL; 114 | SCOSSL_STATUS ret = SCOSSL_FAILURE; 115 | 116 | if (keyCtx == NULL) 117 | { 118 | ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); 119 | goto cleanup; 120 | } 121 | 122 | if (ctx->desc->encodeInternal == NULL || 123 | keyAbstract != NULL || 124 | (ctx->desc->outFormat != SCOSSL_ENCODE_TEXT && ((selection & ctx->desc->selection) == 0))) 125 | { 126 | ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT); 127 | goto cleanup; 128 | } 129 | 130 | if ((bio = p_scossl_bio_new_from_core_bio(ctx->provctx, out)) != NULL) 131 | { 132 | ret = ctx->desc->encodeInternal( 133 | ctx, bio, 134 | keyCtx, 135 | selection, 136 | passphraseCb, passphraseCbArgs); 137 | } 138 | 139 | cleanup: 140 | BIO_free(bio); 141 | 142 | return ret; 143 | } 144 | 145 | _Use_decl_annotations_ 146 | SCOSSL_STATUS p_scossl_encode_write_key_bytes(PCBYTE pbKey, SIZE_T cbKey, BIO *out) 147 | { 148 | for(SIZE_T i = 0; i < cbKey; i++) 149 | { 150 | if (i % KEY_TO_TEXT_PRINT_WIDTH == 0) 151 | { 152 | if (BIO_printf(out, "\n ") <= 0) 153 | { 154 | return SCOSSL_FAILURE; 155 | } 156 | } 157 | 158 | if (BIO_printf(out, "%02x%s", pbKey[i], (i < cbKey - 1) ? ":" : "\n") <= 0) 159 | { 160 | return SCOSSL_FAILURE; 161 | } 162 | } 163 | 164 | return SCOSSL_SUCCESS; 165 | } 166 | 167 | #ifdef __cplusplus 168 | } 169 | #endif -------------------------------------------------------------------------------- /SymCryptProvider/src/encoder/p_scossl_encode_common.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include "p_scossl_base.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #define select_PrivateKeyInfo OSSL_KEYMGMT_SELECT_PRIVATE_KEY 12 | #define select_EncryptedPrivateKeyInfo OSSL_KEYMGMT_SELECT_PRIVATE_KEY 13 | #define select_SubjectPublicKeyInfo OSSL_KEYMGMT_SELECT_PUBLIC_KEY 14 | 15 | typedef enum { 16 | SCOSSL_ENCODE_DER = 1, 17 | SCOSSL_ENCODE_PEM, 18 | SCOSSL_ENCODE_TEXT 19 | } SCOSSL_ENCODE_OUT_FORMAT; 20 | 21 | typedef SCOSSL_STATUS (*PSCOSSL_ENCODE_INTERNAL_FN) (_In_ PVOID encodeCtx, _Inout_ BIO *out, 22 | _In_ PCVOID keyCtx, 23 | int selection, 24 | _In_ OSSL_PASSPHRASE_CALLBACK *passphraseCb, _In_ void *passphraseCbArgs); 25 | 26 | typedef struct 27 | { 28 | int selection; 29 | SCOSSL_ENCODE_OUT_FORMAT outFormat; 30 | 31 | PSCOSSL_ENCODE_INTERNAL_FN encodeInternal; 32 | } SCOSSL_ENCODE_KEYTYPE_DESC; 33 | 34 | typedef struct 35 | { 36 | SCOSSL_PROVCTX *provctx; 37 | 38 | EVP_CIPHER *cipher; 39 | 40 | const SCOSSL_ENCODE_KEYTYPE_DESC *desc; 41 | } SCOSSL_ENCODE_CTX; 42 | 43 | SCOSSL_ENCODE_CTX *p_scossl_encode_newctx(_In_ SCOSSL_PROVCTX *provctx, const SCOSSL_ENCODE_KEYTYPE_DESC *desc); 44 | void p_scossl_encode_freectx(_Inout_ SCOSSL_ENCODE_CTX *ctx); 45 | 46 | SCOSSL_STATUS p_scossl_encode_set_ctx_params(_In_ SCOSSL_ENCODE_CTX *ctx, _In_ const OSSL_PARAM params[]); 47 | const OSSL_PARAM *p_scossl_encode_settable_ctx_params(ossl_unused void *provctx); 48 | 49 | BOOL p_scossl_encode_does_selection(_In_ const SCOSSL_ENCODE_KEYTYPE_DESC *desc, int selection); 50 | 51 | SCOSSL_STATUS p_scossl_encode(_In_ SCOSSL_ENCODE_CTX *ctx, _In_ OSSL_CORE_BIO *coreOut, 52 | _In_ const void *keyCtx, 53 | _In_ const OSSL_PARAM keyAbstract[], 54 | int selection, 55 | _In_ OSSL_PASSPHRASE_CALLBACK *passphraseCb, _In_ void *passphraseCbArgs); 56 | 57 | SCOSSL_STATUS p_scossl_encode_write_key_bytes(_In_reads_bytes_(cbKey) PCBYTE pbKey, SIZE_T cbKey, _Inout_ BIO *out); 58 | 59 | #ifdef __cplusplus 60 | } 61 | #endif -------------------------------------------------------------------------------- /SymCryptProvider/src/kdf/p_scossl_hkdf.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #pragma once 6 | 7 | #include "scossl_hkdf.h" 8 | #include "p_scossl_base.h" 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | typedef struct 15 | { 16 | // Needed for fetching md 17 | OSSL_LIB_CTX *libctx; 18 | 19 | SCOSSL_HKDF_CTX *hkdfCtx; 20 | } SCOSSL_PROV_HKDF_CTX; 21 | 22 | SCOSSL_PROV_HKDF_CTX *p_scossl_hkdf_newctx(_In_ SCOSSL_PROVCTX *provctx); 23 | void p_scossl_hkdf_freectx(_Inout_ SCOSSL_PROV_HKDF_CTX *ctx); 24 | SCOSSL_PROV_HKDF_CTX *p_scossl_hkdf_dupctx(_In_ SCOSSL_PROV_HKDF_CTX *ctx); 25 | 26 | SCOSSL_STATUS p_scossl_hkdf_derive(_In_ SCOSSL_PROV_HKDF_CTX *ctx, 27 | _Out_writes_bytes_(keylen) unsigned char *key, size_t keylen, 28 | _In_ const OSSL_PARAM params[]); 29 | 30 | const OSSL_PARAM *p_scossl_hkdf_gettable_ctx_params(ossl_unused void *ctx, ossl_unused void *provctx); 31 | const OSSL_PARAM *p_scossl_hkdf_settable_ctx_params(ossl_unused void *ctx, ossl_unused void *provctx); 32 | SCOSSL_STATUS p_scossl_hkdf_get_ctx_params(_In_ SCOSSL_PROV_HKDF_CTX *ctx, _Inout_ OSSL_PARAM params[]); 33 | SCOSSL_STATUS p_scossl_hkdf_set_ctx_params(_Inout_ SCOSSL_PROV_HKDF_CTX *ctx, const _In_ OSSL_PARAM params[]); 34 | 35 | #ifdef __cplusplus 36 | } 37 | #endif -------------------------------------------------------------------------------- /SymCryptProvider/src/kdf/p_scossl_tls1prf.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #pragma once 6 | 7 | #include "scossl_tls1prf.h" 8 | #include "p_scossl_base.h" 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | typedef struct { 15 | // Needed for fetching md 16 | OSSL_LIB_CTX *libctx; 17 | 18 | // Purely informational 19 | char *mdName; 20 | 21 | SCOSSL_TLS1_PRF_CTX *tls1prfCtx; 22 | } SCOSSL_PROV_TLS1_PRF_CTX; 23 | 24 | SCOSSL_PROV_TLS1_PRF_CTX *p_scossl_tls1prf_newctx(_In_ SCOSSL_PROVCTX *provctx); 25 | void p_scossl_tls1prf_freectx(_Inout_ SCOSSL_PROV_TLS1_PRF_CTX *ctx); 26 | SCOSSL_PROV_TLS1_PRF_CTX *p_scossl_tls1prf_dupctx(_In_ SCOSSL_PROV_TLS1_PRF_CTX *ctx); 27 | 28 | SCOSSL_STATUS p_scossl_tls1prf_derive(_In_ SCOSSL_PROV_TLS1_PRF_CTX *ctx, 29 | _Out_writes_bytes_(keylen) unsigned char *key, size_t keylen, 30 | _In_ const OSSL_PARAM params[]); 31 | 32 | const OSSL_PARAM *p_scossl_tls1prf_gettable_ctx_params(ossl_unused void *ctx, ossl_unused void *provctx); 33 | const OSSL_PARAM *p_scossl_tls1prf_settable_ctx_params(ossl_unused void *ctx, ossl_unused void *provctx); 34 | SCOSSL_STATUS p_scossl_tls1prf_get_ctx_params(_In_ SCOSSL_PROV_TLS1_PRF_CTX *ctx, _Inout_ OSSL_PARAM params[]); 35 | SCOSSL_STATUS p_scossl_tls1prf_set_ctx_params(_Inout_ SCOSSL_PROV_TLS1_PRF_CTX *ctx, const _In_ OSSL_PARAM params[]); 36 | 37 | #ifdef __cplusplus 38 | } 39 | #endif -------------------------------------------------------------------------------- /SymCryptProvider/src/kem/p_scossl_mlkem.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include "p_scossl_base.h" 6 | #include "p_scossl_ecc.h" 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | typedef struct { 13 | int nid; 14 | const char *oid; 15 | const char *snGroupName; 16 | const char *lnGroupName; 17 | const char *classicGroupName; 18 | SYMCRYPT_MLKEM_PARAMS mlkemParams; 19 | } SCOSSL_MLKEM_GROUP_INFO; 20 | 21 | typedef struct { 22 | SCOSSL_PROVCTX *provCtx; 23 | 24 | const SCOSSL_MLKEM_GROUP_INFO *groupInfo; 25 | PSYMCRYPT_MLKEMKEY key; 26 | SYMCRYPT_MLKEMKEY_FORMAT format; 27 | 28 | SCOSSL_ECC_KEY_CTX *classicKeyCtx; 29 | } SCOSSL_MLKEM_KEY_CTX; 30 | 31 | BOOL p_scossl_mlkem_is_hybrid(_In_ const SCOSSL_MLKEM_KEY_CTX *ctx); 32 | 33 | SCOSSL_STATUS p_scossl_mlkem_register_algorithms(); 34 | SCOSSL_MLKEM_GROUP_INFO *p_scossl_mlkem_get_group_info_by_nid(int nid); 35 | SCOSSL_MLKEM_GROUP_INFO *p_scossl_mlkem_get_group_info(_In_ const char *groupName); 36 | 37 | #ifdef __cplusplus 38 | } 39 | #endif -------------------------------------------------------------------------------- /SymCryptProvider/src/keyexch/p_scossl_dh.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include "scossl_dh.h" 6 | #include "p_scossl_base.h" 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | typedef struct 13 | { 14 | // Provider needs to support importing group by parameters. 15 | // pDlGroup may be set by params, or reference a static, known 16 | // named group. If the group is loaded from params it must be 17 | // freed when the context is freed. 18 | PSYMCRYPT_DLGROUP pDlGroup; 19 | SCOSSL_DH_KEY_CTX *keyCtx; 20 | BOOL groupSetByParams; 21 | int nBitsPriv; 22 | OSSL_LIB_CTX *libCtx; 23 | } SCOSSL_PROV_DH_KEY_CTX; 24 | 25 | #ifdef __cplusplus 26 | } 27 | #endif -------------------------------------------------------------------------------- /SymCryptProvider/src/keyexch/p_scossl_ecdh.c: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include "p_scossl_ecc.h" 6 | #include "p_scossl_base.h" 7 | #include "p_scossl_ecdh.h" 8 | 9 | #include 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | static const OSSL_PARAM p_scossl_ecdh_ctx_param_types[] = { 16 | OSSL_PARAM_END}; 17 | 18 | static SCOSSL_STATUS p_scossl_ecdh_set_ctx_params(_Inout_ SCOSSL_ECDH_CTX *ctx, _In_ const OSSL_PARAM params[]); 19 | 20 | _Use_decl_annotations_ 21 | SCOSSL_ECDH_CTX *p_scossl_ecdh_newctx(SCOSSL_PROVCTX *provctx) 22 | { 23 | SCOSSL_ECDH_CTX *ctx = OPENSSL_malloc(sizeof(SCOSSL_ECDH_CTX)); 24 | if (ctx != NULL) 25 | { 26 | ctx->libctx = provctx->libctx; 27 | ctx->keyCtx = NULL; 28 | ctx->peerKeyCtx = NULL; 29 | } 30 | 31 | return ctx; 32 | } 33 | 34 | _Use_decl_annotations_ 35 | void p_scossl_ecdh_freectx(SCOSSL_ECDH_CTX *ctx) 36 | { 37 | OPENSSL_free(ctx); 38 | } 39 | 40 | _Use_decl_annotations_ 41 | SCOSSL_ECDH_CTX *p_scossl_ecdh_dupctx(SCOSSL_ECDH_CTX *ctx) 42 | { 43 | SCOSSL_ECDH_CTX *copyCtx = OPENSSL_malloc(sizeof(SCOSSL_ECDH_CTX)); 44 | if (copyCtx != NULL) 45 | { 46 | copyCtx->libctx = ctx->libctx; 47 | copyCtx->keyCtx = ctx->keyCtx; 48 | copyCtx->peerKeyCtx = ctx->peerKeyCtx; 49 | } 50 | 51 | return copyCtx; 52 | } 53 | 54 | _Use_decl_annotations_ 55 | SCOSSL_STATUS p_scossl_ecdh_init(SCOSSL_ECDH_CTX *ctx, SCOSSL_ECC_KEY_CTX *keyCtx, 56 | ossl_unused const OSSL_PARAM params[]) 57 | { 58 | if (ctx == NULL || keyCtx == NULL) 59 | { 60 | return SCOSSL_FAILURE; 61 | } 62 | ctx->keyCtx = keyCtx; 63 | 64 | // No parameters are currently accepted for this interface. 65 | // Return the result of p_scossl_ecdh_set_ctx_params if this changes. 66 | return SCOSSL_SUCCESS; 67 | } 68 | 69 | _Use_decl_annotations_ 70 | SCOSSL_STATUS p_scossl_ecdh_set_peer(SCOSSL_ECDH_CTX *ctx, SCOSSL_ECC_KEY_CTX *peerKeyCtx) 71 | { 72 | SCOSSL_STATUS ret = SCOSSL_FAILURE; 73 | 74 | if (ctx == NULL || peerKeyCtx == NULL) 75 | { 76 | ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); 77 | goto cleanup; 78 | } 79 | 80 | if (!SymCryptEcurveIsSame(ctx->keyCtx->curve, peerKeyCtx->curve)) 81 | { 82 | ERR_raise(ERR_LIB_PROV, PROV_R_MISMATCHING_DOMAIN_PARAMETERS); 83 | goto cleanup; 84 | } 85 | 86 | ctx->peerKeyCtx = peerKeyCtx; 87 | ret = SCOSSL_SUCCESS; 88 | 89 | cleanup: 90 | 91 | return ret; 92 | } 93 | 94 | _Use_decl_annotations_ 95 | SCOSSL_STATUS p_scossl_ecdh_derive(SCOSSL_ECDH_CTX *ctx, 96 | unsigned char *secret, size_t *secretlen, 97 | size_t outlen) 98 | { 99 | PBYTE pbSecret = secret; 100 | PBYTE pbSecretBuf = NULL; 101 | SIZE_T cbSecretBuf = 0; 102 | SCOSSL_STATUS ret = SCOSSL_FAILURE; 103 | SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR; 104 | SYMCRYPT_NUMBER_FORMAT numberFormat; 105 | 106 | if (ctx == NULL || secretlen == NULL) 107 | { 108 | ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); 109 | return SCOSSL_FAILURE; 110 | } 111 | 112 | if (ctx->keyCtx == NULL || 113 | (secret != NULL && ctx->peerKeyCtx == NULL)) { 114 | ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_KEY); 115 | return SCOSSL_FAILURE; 116 | } 117 | 118 | cbSecretBuf = SymCryptEckeySizeofPublicKey(ctx->keyCtx->key, SYMCRYPT_ECPOINT_FORMAT_X); 119 | if (secret == NULL) 120 | { 121 | *secretlen = cbSecretBuf; 122 | return SCOSSL_SUCCESS; 123 | } 124 | 125 | numberFormat = ctx->keyCtx->isX25519 ? SYMCRYPT_NUMBER_FORMAT_LSB_FIRST : SYMCRYPT_NUMBER_FORMAT_MSB_FIRST; 126 | 127 | if (outlen < cbSecretBuf) 128 | { 129 | if ((pbSecretBuf = OPENSSL_secure_malloc(cbSecretBuf)) == NULL) 130 | { 131 | ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); 132 | goto cleanup; 133 | } 134 | 135 | pbSecret = pbSecretBuf; 136 | } 137 | 138 | scError = SymCryptEcDhSecretAgreement( 139 | ctx->keyCtx->key, 140 | ctx->peerKeyCtx->key, 141 | numberFormat, 142 | 0, 143 | pbSecret, 144 | cbSecretBuf); 145 | if (scError != SYMCRYPT_NO_ERROR) 146 | { 147 | SCOSSL_PROV_LOG_SYMCRYPT_ERROR("SymCryptEcDhSecretAgreement failed", scError); 148 | goto cleanup; 149 | } 150 | 151 | if (outlen < cbSecretBuf) 152 | { 153 | memcpy(secret, pbSecretBuf, outlen); 154 | *secretlen = outlen; 155 | } 156 | else 157 | { 158 | *secretlen = cbSecretBuf; 159 | } 160 | 161 | ret = SCOSSL_SUCCESS; 162 | 163 | cleanup: 164 | OPENSSL_secure_clear_free(pbSecretBuf, cbSecretBuf); 165 | 166 | return ret; 167 | } 168 | 169 | // This implementation currently does not accept any parameters 170 | static SCOSSL_STATUS p_scossl_ecdh_set_ctx_params(ossl_unused SCOSSL_ECDH_CTX *ctx, ossl_unused const OSSL_PARAM params[]) 171 | { 172 | return SCOSSL_SUCCESS; 173 | } 174 | 175 | static SCOSSL_STATUS p_scossl_ecdh_get_ctx_params(ossl_unused SCOSSL_ECDH_CTX *ctx, ossl_unused OSSL_PARAM params[]) 176 | { 177 | return SCOSSL_SUCCESS; 178 | } 179 | 180 | static const OSSL_PARAM *p_scossl_ecdh_ctx_params(ossl_unused void *ctx, ossl_unused void *provctx) 181 | { 182 | return p_scossl_ecdh_ctx_param_types; 183 | } 184 | 185 | const OSSL_DISPATCH p_scossl_ecdh_functions[] = { 186 | {OSSL_FUNC_KEYEXCH_NEWCTX, (void (*)(void))p_scossl_ecdh_newctx}, 187 | {OSSL_FUNC_KEYEXCH_FREECTX, (void (*)(void))p_scossl_ecdh_freectx}, 188 | {OSSL_FUNC_KEYEXCH_DUPCTX, (void (*)(void))p_scossl_ecdh_dupctx}, 189 | {OSSL_FUNC_KEYEXCH_INIT, (void (*)(void))p_scossl_ecdh_init}, 190 | {OSSL_FUNC_KEYEXCH_SET_PEER, (void (*)(void))p_scossl_ecdh_set_peer}, 191 | {OSSL_FUNC_KEYEXCH_DERIVE, (void (*)(void))p_scossl_ecdh_derive}, 192 | {OSSL_FUNC_KEYEXCH_SET_CTX_PARAMS, (void (*)(void))p_scossl_ecdh_set_ctx_params}, 193 | {OSSL_FUNC_KEYEXCH_SETTABLE_CTX_PARAMS, (void (*)(void))p_scossl_ecdh_ctx_params}, 194 | {OSSL_FUNC_KEYEXCH_GET_CTX_PARAMS, (void (*)(void))p_scossl_ecdh_get_ctx_params}, 195 | {OSSL_FUNC_KEYEXCH_GETTABLE_CTX_PARAMS, (void (*)(void))p_scossl_ecdh_ctx_params}, 196 | {0, NULL}}; 197 | 198 | #ifdef __cplusplus 199 | } 200 | #endif -------------------------------------------------------------------------------- /SymCryptProvider/src/keyexch/p_scossl_ecdh.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include "scossl_ecc.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | typedef struct 12 | { 13 | OSSL_LIB_CTX *libctx; 14 | SCOSSL_ECC_KEY_CTX *keyCtx; 15 | SCOSSL_ECC_KEY_CTX *peerKeyCtx; 16 | } SCOSSL_ECDH_CTX; 17 | 18 | // ECDH functions are exposed here for use in hybrid key exchange 19 | SCOSSL_ECDH_CTX *p_scossl_ecdh_newctx(_In_ SCOSSL_PROVCTX *provctx); 20 | void p_scossl_ecdh_freectx(_In_ SCOSSL_ECDH_CTX *ctx); 21 | SCOSSL_ECDH_CTX *p_scossl_ecdh_dupctx(_In_ SCOSSL_ECDH_CTX *ctx); 22 | 23 | SCOSSL_STATUS p_scossl_ecdh_init(_In_ SCOSSL_ECDH_CTX *ctx, _In_ SCOSSL_ECC_KEY_CTX *keyCtx, 24 | ossl_unused const OSSL_PARAM params[]); 25 | SCOSSL_STATUS p_scossl_ecdh_set_peer(_Inout_ SCOSSL_ECDH_CTX *ctx, _In_ SCOSSL_ECC_KEY_CTX *peerKeyCtx); 26 | SCOSSL_STATUS p_scossl_ecdh_derive(_In_ SCOSSL_ECDH_CTX *ctx, 27 | _Out_writes_bytes_opt_(*secretlen) unsigned char *secret, _Out_ size_t *secretlen, 28 | size_t outlen); 29 | 30 | 31 | #ifdef __cplusplus 32 | } 33 | #endif -------------------------------------------------------------------------------- /SymCryptProvider/src/keymgmt/p_scossl_ecc_keymgmt.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include 6 | #include 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | // Parameter types for import/export depend on the selection 13 | // passed by the caller. These can be any combination of: 14 | // OSSL_KEYMGMT_SELECT_PRIVATE_KEY 15 | // OSSL_KEYMGMT_SELECT_PUBLIC_KEY 16 | // OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS 17 | // OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS 18 | // Rather than constructing the parameter array each time 19 | // a caller queries supported parameters, these values 20 | // are hardcoded here. This follows the same pattern as 21 | // the default provider. 22 | 23 | #define SCOSSL_ECC_IMPEXP_PRIV_KEY_PARAMS \ 24 | OSSL_PARAM_BN(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0), 25 | 26 | #define SCOSSL_ECC_IMPEXP_PUB_KEY_PARAMS \ 27 | OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0), 28 | 29 | #define SCOSSL_ECC_IMPEXP_DOMAIN_PARAMS \ 30 | OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0), \ 31 | OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_ENCODING, NULL, 0), 32 | 33 | #define SCOSSL_ECC_IMPEXP_OTHER_PARAMS \ 34 | OSSL_PARAM_int(OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, NULL), \ 35 | OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_INCLUDE_PUBLIC, NULL), \ 36 | OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, NULL, 0), 37 | 38 | // OSSL_KEYMGMT_SELECT_PRIVATE_KEY 39 | static const OSSL_PARAM p_scossl_ecc_impexp_types_0x01[] = { 40 | SCOSSL_ECC_IMPEXP_PRIV_KEY_PARAMS 41 | OSSL_PARAM_END}; 42 | 43 | // OSSL_KEYMGMT_SELECT_PUBLIC_KEY 44 | static const OSSL_PARAM p_scossl_ecc_impexp_types_0x02[] = { 45 | SCOSSL_ECC_IMPEXP_PUB_KEY_PARAMS 46 | OSSL_PARAM_END}; 47 | 48 | // OSSL_KEYMGMT_SELECT_PRIVATE_KEY 49 | // OSSL_KEYMGMT_SELECT_PUBLIC_KEY 50 | static const OSSL_PARAM p_scossl_ecc_impexp_types_0x03[] = { 51 | SCOSSL_ECC_IMPEXP_PRIV_KEY_PARAMS 52 | SCOSSL_ECC_IMPEXP_PUB_KEY_PARAMS 53 | OSSL_PARAM_END}; 54 | 55 | // OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS 56 | static const OSSL_PARAM p_scossl_ecc_impexp_types_0x04[] = { 57 | SCOSSL_ECC_IMPEXP_DOMAIN_PARAMS 58 | OSSL_PARAM_END}; 59 | 60 | // OSSL_KEYMGMT_SELECT_PRIVATE_KEY 61 | // OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS 62 | static const OSSL_PARAM p_scossl_ecc_impexp_types_0x05[] = { 63 | SCOSSL_ECC_IMPEXP_PRIV_KEY_PARAMS 64 | SCOSSL_ECC_IMPEXP_DOMAIN_PARAMS 65 | OSSL_PARAM_END}; 66 | 67 | // OSSL_KEYMGMT_SELECT_PUBLIC_KEY 68 | // OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS 69 | static const OSSL_PARAM p_scossl_ecc_impexp_types_0x06[] = { 70 | SCOSSL_ECC_IMPEXP_PUB_KEY_PARAMS 71 | SCOSSL_ECC_IMPEXP_DOMAIN_PARAMS 72 | OSSL_PARAM_END}; 73 | 74 | // OSSL_KEYMGMT_SELECT_PRIVATE_KEY 75 | // OSSL_KEYMGMT_SELECT_PUBLIC_KEY 76 | // OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS 77 | static const OSSL_PARAM p_scossl_ecc_impexp_types_0x07[] = { 78 | SCOSSL_ECC_IMPEXP_PRIV_KEY_PARAMS 79 | SCOSSL_ECC_IMPEXP_PUB_KEY_PARAMS 80 | SCOSSL_ECC_IMPEXP_DOMAIN_PARAMS 81 | OSSL_PARAM_END}; 82 | 83 | // OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS 84 | static const OSSL_PARAM p_scossl_ecc_impexp_types_0x08[] = { 85 | SCOSSL_ECC_IMPEXP_OTHER_PARAMS 86 | OSSL_PARAM_END}; 87 | 88 | // OSSL_KEYMGMT_SELECT_PRIVATE_KEY 89 | // OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS 90 | static const OSSL_PARAM p_scossl_ecc_impexp_types_0x09[] = { 91 | SCOSSL_ECC_IMPEXP_PRIV_KEY_PARAMS 92 | SCOSSL_ECC_IMPEXP_OTHER_PARAMS 93 | OSSL_PARAM_END}; 94 | 95 | // OSSL_KEYMGMT_SELECT_PUBLIC_KEY 96 | // OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS 97 | static const OSSL_PARAM p_scossl_ecc_impexp_types_0x0a[] = { 98 | SCOSSL_ECC_IMPEXP_PUB_KEY_PARAMS 99 | SCOSSL_ECC_IMPEXP_OTHER_PARAMS 100 | OSSL_PARAM_END}; 101 | 102 | // OSSL_KEYMGMT_SELECT_PRIVATE_KEY 103 | // OSSL_KEYMGMT_SELECT_PUBLIC_KEY 104 | // OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS 105 | static const OSSL_PARAM p_scossl_ecc_impexp_types_0x0b[] = { 106 | SCOSSL_ECC_IMPEXP_PRIV_KEY_PARAMS 107 | SCOSSL_ECC_IMPEXP_PUB_KEY_PARAMS 108 | SCOSSL_ECC_IMPEXP_OTHER_PARAMS 109 | OSSL_PARAM_END}; 110 | 111 | // OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS 112 | // OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS 113 | static const OSSL_PARAM p_scossl_ecc_impexp_types_0x0c[] = { 114 | SCOSSL_ECC_IMPEXP_DOMAIN_PARAMS 115 | SCOSSL_ECC_IMPEXP_OTHER_PARAMS 116 | OSSL_PARAM_END}; 117 | 118 | // OSSL_KEYMGMT_SELECT_PRIVATE_KEY 119 | // OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS 120 | // OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS 121 | static const OSSL_PARAM p_scossl_ecc_impexp_types_0x0d[] = { 122 | SCOSSL_ECC_IMPEXP_PRIV_KEY_PARAMS 123 | SCOSSL_ECC_IMPEXP_DOMAIN_PARAMS 124 | SCOSSL_ECC_IMPEXP_OTHER_PARAMS 125 | OSSL_PARAM_END}; 126 | 127 | // OSSL_KEYMGMT_SELECT_PUBLIC_KEY 128 | // OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS 129 | // OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS 130 | static const OSSL_PARAM p_scossl_ecc_impexp_types_0x0e[] = { 131 | SCOSSL_ECC_IMPEXP_PUB_KEY_PARAMS 132 | SCOSSL_ECC_IMPEXP_DOMAIN_PARAMS 133 | SCOSSL_ECC_IMPEXP_OTHER_PARAMS 134 | OSSL_PARAM_END}; 135 | 136 | // OSSL_KEYMGMT_SELECT_PRIVATE_KEY 137 | // OSSL_KEYMGMT_SELECT_PUBLIC_KEY 138 | // OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS 139 | // OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS 140 | static const OSSL_PARAM p_scossl_ecc_impexp_types_0x0f[] = { 141 | SCOSSL_ECC_IMPEXP_PRIV_KEY_PARAMS 142 | SCOSSL_ECC_IMPEXP_PUB_KEY_PARAMS 143 | SCOSSL_ECC_IMPEXP_DOMAIN_PARAMS 144 | SCOSSL_ECC_IMPEXP_OTHER_PARAMS 145 | OSSL_PARAM_END}; 146 | 147 | static const OSSL_PARAM *p_scossl_ecc_keymgmt_impexp_param_types[] = { 148 | NULL, 149 | p_scossl_ecc_impexp_types_0x01, 150 | p_scossl_ecc_impexp_types_0x02, 151 | p_scossl_ecc_impexp_types_0x03, 152 | p_scossl_ecc_impexp_types_0x04, 153 | p_scossl_ecc_impexp_types_0x05, 154 | p_scossl_ecc_impexp_types_0x06, 155 | p_scossl_ecc_impexp_types_0x07, 156 | p_scossl_ecc_impexp_types_0x08, 157 | p_scossl_ecc_impexp_types_0x09, 158 | p_scossl_ecc_impexp_types_0x0a, 159 | p_scossl_ecc_impexp_types_0x0b, 160 | p_scossl_ecc_impexp_types_0x0c, 161 | p_scossl_ecc_impexp_types_0x0d, 162 | p_scossl_ecc_impexp_types_0x0e, 163 | p_scossl_ecc_impexp_types_0x0f}; 164 | 165 | #ifdef __cplusplus 166 | } 167 | #endif -------------------------------------------------------------------------------- /SymCryptProvider/src/keymgmt/p_scossl_kdf_keymgmt.c: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | // Before OpenSSL 3, HKDF and TLS1-PRF were available through the EVP_PKEY API. 6 | // In OpenSSL 3, these are available through the EVP_KDF API, which uses the 7 | // provider kdf interface. Some callers may still be using the EVP_PKEY API 8 | // for HKDF and TLS1-PRF. The implementations in keyexch/p_scossl_kdf_keyexch 9 | // provide HKDF and TLS1-PRF for the EVP_PKEY API. This keymgmt interface is 10 | // mostly empty but necessary to expose both KDFs through the EVP_PKEY API. 11 | 12 | #include "scossl_helpers.h" 13 | 14 | #include 15 | 16 | #ifdef __cplusplus 17 | extern "C" { 18 | #endif 19 | 20 | static const BYTE dummy_kdf_keymgmt_ctx = 0; 21 | 22 | const BYTE *p_scossl_kdf_keymgmt_new_ctx(ossl_unused void *provctx) 23 | { 24 | return &dummy_kdf_keymgmt_ctx; 25 | } 26 | 27 | void p_scossl_kdf_keymgmt_free_ctx(ossl_unused void *keyCtx){} 28 | 29 | static BOOL p_scossl_kdf_keymgmt_has(ossl_unused const void *keydata, ossl_unused int selection) 30 | { 31 | return TRUE; 32 | } 33 | 34 | const OSSL_DISPATCH p_scossl_kdf_keymgmt_functions[] = { 35 | {OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))p_scossl_kdf_keymgmt_new_ctx}, 36 | {OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))p_scossl_kdf_keymgmt_free_ctx}, 37 | {OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))p_scossl_kdf_keymgmt_has}, 38 | {0, NULL}}; 39 | 40 | #ifdef __cplusplus 41 | } 42 | #endif -------------------------------------------------------------------------------- /SymCryptProvider/src/keymgmt/p_scossl_mlkem_keymgmt.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #pragma once 6 | 7 | #include "p_scossl_base.h" 8 | #include "kem/p_scossl_mlkem.h" 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | SCOSSL_MLKEM_KEY_CTX *p_scossl_mlkem_keymgmt_new_ctx(_In_ SCOSSL_PROVCTX *provCtx); 15 | void p_scossl_mlkem_keymgmt_free_key_ctx(_In_ SCOSSL_MLKEM_KEY_CTX *keyCtx); 16 | 17 | SCOSSL_STATUS p_scossl_mlkem_keymgmt_import(_Inout_ SCOSSL_MLKEM_KEY_CTX *keyCtx, int selection, _In_ const OSSL_PARAM params[]); 18 | SCOSSL_STATUS p_scossl_mlkem_keymgmt_export(_In_ SCOSSL_MLKEM_KEY_CTX *keyCtx, int selection, 19 | _In_ OSSL_CALLBACK *param_cb, _In_ void *cbarg); 20 | 21 | SCOSSL_STATUS p_scossl_mlkem_keymgmt_get_encoded_key(_In_ const SCOSSL_MLKEM_KEY_CTX *keyCtx, int selection, 22 | _Out_writes_bytes_(*pcbKey) PBYTE *ppbKey, _Out_ SIZE_T *pcbKey); 23 | SCOSSL_STATUS p_scossl_mlkem_keymgmt_set_encoded_key(_Inout_ SCOSSL_MLKEM_KEY_CTX *keyCtx, int selection, 24 | _In_reads_bytes_(cbKey) PCBYTE pbKey, SIZE_T cbKey); 25 | 26 | #ifdef __cplusplus 27 | } 28 | #endif -------------------------------------------------------------------------------- /SymCryptProvider/src/mac/p_scossl_cmac.c: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include "scossl_mac.h" 6 | #include "p_scossl_base.h" 7 | 8 | #include 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | static const OSSL_PARAM p_scossl_cmac_ctx_gettable_param_types[] = { 15 | OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL), 16 | OSSL_PARAM_size_t(OSSL_MAC_PARAM_BLOCK_SIZE, NULL), 17 | OSSL_PARAM_END}; 18 | 19 | static const OSSL_PARAM p_scossl_cmac_ctx_settable_param_types[] = { 20 | OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_CIPHER, NULL, 0), 21 | OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_PROPERTIES, NULL, 0), 22 | OSSL_PARAM_octet_string(OSSL_MAC_PARAM_KEY, NULL, 0), 23 | OSSL_PARAM_END}; 24 | 25 | static SCOSSL_STATUS p_scossl_cmac_set_ctx_params(_Inout_ SCOSSL_MAC_CTX *ctx, _In_ const OSSL_PARAM params[]); 26 | 27 | static SCOSSL_MAC_CTX *p_scossl_cmac_newctx(_In_ SCOSSL_PROVCTX *provctx) 28 | { 29 | SCOSSL_MAC_CTX *ctx = OPENSSL_zalloc(sizeof(SCOSSL_MAC_CTX)); 30 | if (ctx != NULL) 31 | { 32 | ctx->libctx = provctx->libctx; 33 | } 34 | 35 | return ctx; 36 | } 37 | 38 | static SCOSSL_STATUS p_scossl_cmac_init(_Inout_ SCOSSL_MAC_CTX *ctx, 39 | _In_reads_bytes_opt_(keylen) unsigned char *key, size_t keylen, 40 | _In_ const OSSL_PARAM params[]) 41 | { 42 | return p_scossl_cmac_set_ctx_params(ctx, params) && 43 | scossl_mac_init(ctx, key, keylen); 44 | 45 | } 46 | 47 | static const OSSL_PARAM *p_scossl_cmac_gettable_ctx_params(ossl_unused void *ctx, ossl_unused void *provctx) 48 | { 49 | return p_scossl_cmac_ctx_gettable_param_types; 50 | } 51 | 52 | static const OSSL_PARAM *p_scossl_cmac_settable_ctx_params(ossl_unused void *ctx, ossl_unused void *provctx) 53 | { 54 | return p_scossl_cmac_ctx_settable_param_types; 55 | } 56 | 57 | static SCOSSL_STATUS p_scossl_cmac_get_ctx_params(_In_ SCOSSL_MAC_CTX *ctx, _Inout_ OSSL_PARAM params[]) 58 | { 59 | OSSL_PARAM *p; 60 | 61 | if ((p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_SIZE)) != NULL && 62 | !OSSL_PARAM_set_size_t(p, ctx->pMac == NULL ? 0 : ctx->pMac->resultSize)) 63 | { 64 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); 65 | return SCOSSL_FAILURE; 66 | } 67 | 68 | if ((p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_BLOCK_SIZE)) != NULL && 69 | !OSSL_PARAM_set_size_t(p, ctx->pMacEx == NULL ? 0 : ctx->pMacEx->blockSize)) 70 | { 71 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); 72 | return SCOSSL_FAILURE; 73 | } 74 | 75 | return SCOSSL_SUCCESS; 76 | } 77 | 78 | static SCOSSL_STATUS p_scossl_cmac_set_ctx_params(_Inout_ SCOSSL_MAC_CTX *ctx, _In_ const OSSL_PARAM params[]) 79 | { 80 | const OSSL_PARAM *p; 81 | 82 | if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_CIPHER)) != NULL) 83 | { 84 | SCOSSL_STATUS success; 85 | const char *cipherName, *cipherProps; 86 | EVP_CIPHER *cipher; 87 | 88 | if (!OSSL_PARAM_get_utf8_string_ptr(p, &cipherName)) 89 | { 90 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); 91 | return SCOSSL_FAILURE; 92 | } 93 | 94 | cipherProps = NULL; 95 | p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_PROPERTIES); 96 | if ((p != NULL && !OSSL_PARAM_get_utf8_string_ptr(p, &cipherProps)) || 97 | (cipher = EVP_CIPHER_fetch(ctx->libctx, cipherName, cipherProps)) == NULL) 98 | { 99 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); 100 | return SCOSSL_FAILURE; 101 | } 102 | 103 | success = scossl_mac_set_cmac_cipher(ctx, cipher); 104 | EVP_CIPHER_free(cipher); 105 | 106 | if (!success) 107 | { 108 | ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_MODE); 109 | return SCOSSL_FAILURE; 110 | } 111 | } 112 | 113 | if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_KEY)) != NULL) 114 | { 115 | PCBYTE pbMacKey; 116 | SIZE_T cbMacKey; 117 | if (!OSSL_PARAM_get_octet_string_ptr(p, (const void **)&pbMacKey, &cbMacKey) || 118 | !scossl_mac_init(ctx, pbMacKey, cbMacKey)) 119 | { 120 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); 121 | return SCOSSL_FAILURE; 122 | } 123 | } 124 | 125 | return SCOSSL_SUCCESS; 126 | } 127 | 128 | const OSSL_DISPATCH p_scossl_cmac_functions[] = { 129 | {OSSL_FUNC_MAC_NEWCTX, (void (*)(void))p_scossl_cmac_newctx}, 130 | {OSSL_FUNC_MAC_FREECTX, (void (*)(void))scossl_mac_freectx}, 131 | {OSSL_FUNC_MAC_DUPCTX, (void (*)(void))scossl_mac_dupctx}, 132 | {OSSL_FUNC_MAC_INIT, (void (*)(void))p_scossl_cmac_init}, 133 | {OSSL_FUNC_MAC_UPDATE, (void (*)(void))scossl_mac_update}, 134 | {OSSL_FUNC_MAC_FINAL, (void (*)(void))scossl_mac_final}, 135 | {OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS, (void (*)(void))p_scossl_cmac_gettable_ctx_params}, 136 | {OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS, (void (*)(void))p_scossl_cmac_settable_ctx_params}, 137 | {OSSL_FUNC_MAC_GET_CTX_PARAMS, (void (*)(void))p_scossl_cmac_get_ctx_params}, 138 | {OSSL_FUNC_MAC_SET_CTX_PARAMS, (void (*)(void))p_scossl_cmac_set_ctx_params}, 139 | {0, NULL}}; 140 | 141 | #ifdef __cplusplus 142 | } 143 | #endif -------------------------------------------------------------------------------- /SymCryptProvider/src/mac/p_scossl_kmac.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include "scossl_helpers.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | // These types and constants are used by both KMAC and KBKDF using KMAC 12 | typedef union 13 | { 14 | SYMCRYPT_KMAC128_EXPANDED_KEY kmac128Key; 15 | SYMCRYPT_KMAC256_EXPANDED_KEY kmac256Key; 16 | } SCOSSL_KMAC_EXPANDED_KEY; 17 | 18 | typedef union 19 | { 20 | SYMCRYPT_KMAC128_STATE kmac128State; 21 | SYMCRYPT_KMAC256_STATE kmac256State; 22 | } SCOSSL_KMAC_STATE; 23 | 24 | typedef SYMCRYPT_ERROR (SYMCRYPT_CALL * PSYMCRYPT_KMAC_EXPAND_KEY_EX) 25 | (SCOSSL_KMAC_EXPANDED_KEY *pExpandedKey, PCBYTE pbKey, SIZE_T cbKey, 26 | PCBYTE pbCustomizationString, SIZE_T cbCustomizationString); 27 | typedef VOID (SYMCRYPT_CALL * PSYMCRYPT_KMAC_RESULT_EX) (SCOSSL_KMAC_STATE *pState, PVOID pbResult, SIZE_T cbResult); 28 | typedef VOID (SYMCRYPT_CALL * PSYMCRYPT_KMAC_EXTRACT) (SCOSSL_KMAC_STATE *pState, PVOID pbOutput, SIZE_T cbOutput, BOOLEAN bWipe); 29 | typedef VOID (SYMCRYPT_CALL * PSYMCRYPT_KMAC_KEY_COPY) (SCOSSL_KMAC_EXPANDED_KEY *pSrc, SCOSSL_KMAC_EXPANDED_KEY *pDst); 30 | typedef VOID (SYMCRYPT_CALL * PSYMCRYPT_KMAC_STATE_COPY) (SCOSSL_KMAC_STATE *pSrc, SCOSSL_KMAC_STATE *pDst); 31 | 32 | typedef struct 33 | { 34 | PSYMCRYPT_KMAC_EXPAND_KEY_EX expandKeyExFunc; 35 | PSYMCRYPT_KMAC_RESULT_EX resultExFunc; 36 | PSYMCRYPT_KMAC_EXTRACT extractFunc; 37 | PSYMCRYPT_KMAC_KEY_COPY keyCopyFunc; 38 | PSYMCRYPT_KMAC_STATE_COPY stateCopyFunc; 39 | SIZE_T blockSize; 40 | } SCOSSL_KMAC_EXTENSIONS; 41 | 42 | extern const SCOSSL_KMAC_EXTENSIONS SymCryptKmac128AlgorithmEx; 43 | extern const SCOSSL_KMAC_EXTENSIONS SymCryptKmac256AlgorithmEx; 44 | 45 | #ifdef __cplusplus 46 | } 47 | #endif -------------------------------------------------------------------------------- /SymCryptProvider/src/p_scossl_bio.c: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include "p_scossl_bio.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | OSSL_FUNC_BIO_read_ex_fn *core_bio_read_ex = NULL; 12 | OSSL_FUNC_BIO_write_ex_fn *core_bio_write_ex = NULL; 13 | OSSL_FUNC_BIO_up_ref_fn *core_bio_up_ref = NULL; 14 | OSSL_FUNC_BIO_free_fn *core_bio_free = NULL; 15 | OSSL_FUNC_BIO_gets_fn *core_bio_gets = NULL; 16 | OSSL_FUNC_BIO_puts_fn *core_bio_puts = NULL; 17 | OSSL_FUNC_BIO_ctrl_fn *core_bio_ctrl = NULL; 18 | 19 | static SCOSSL_STATUS p_scossl_bio_core_read_ex(BIO *bio, char *data, size_t data_len, 20 | size_t *bytes_read) 21 | { 22 | if (core_bio_read_ex == NULL) 23 | return SCOSSL_FAILURE; 24 | 25 | return core_bio_read_ex(BIO_get_data(bio), data, data_len, bytes_read); 26 | } 27 | 28 | static SCOSSL_STATUS p_scossl_bio_core_write_ex(BIO *bio, const char *data, size_t data_len, 29 | size_t *written) 30 | { 31 | if (core_bio_write_ex == NULL) 32 | return SCOSSL_FAILURE; 33 | 34 | return core_bio_write_ex(BIO_get_data(bio), data, data_len, written); 35 | } 36 | 37 | static SCOSSL_STATUS p_scossl_bio_core_create(BIO *bio) 38 | { 39 | BIO_set_init(bio, 1); 40 | 41 | return SCOSSL_SUCCESS; 42 | } 43 | 44 | static SCOSSL_STATUS p_scossl_bio_core_destroy(BIO *bio) 45 | { 46 | BIO_set_init(bio, 0); 47 | 48 | if (core_bio_free != NULL) 49 | core_bio_free(BIO_get_data(bio)); 50 | 51 | return SCOSSL_SUCCESS; 52 | } 53 | 54 | static int p_scossl_bio_core_gets(BIO *bio, char *buf, int size) 55 | { 56 | if (core_bio_gets == NULL) 57 | return 0; 58 | 59 | return core_bio_gets(BIO_get_data(bio), buf, size); 60 | } 61 | 62 | static int p_scossl_bio_core_puts(BIO *bio, const char *str) 63 | { 64 | if (core_bio_puts == NULL) 65 | return 0; 66 | 67 | return core_bio_puts(BIO_get_data(bio), str); 68 | } 69 | 70 | static long p_scossl_bio_core_ctrl(BIO *bio, int cmd, long num, void *ptr) 71 | { 72 | if (core_bio_ctrl == NULL) 73 | return 0; 74 | 75 | return core_bio_ctrl(BIO_get_data(bio), cmd, num, ptr); 76 | } 77 | 78 | _Use_decl_annotations_ 79 | void p_scossl_set_core_bio(const OSSL_DISPATCH *dispatch) 80 | { 81 | for (; dispatch->function_id != 0; dispatch++) 82 | { 83 | switch (dispatch->function_id) 84 | { 85 | case OSSL_FUNC_BIO_READ_EX: 86 | core_bio_read_ex = OSSL_FUNC_BIO_read_ex(dispatch); 87 | break; 88 | case OSSL_FUNC_BIO_WRITE_EX: 89 | core_bio_write_ex = OSSL_FUNC_BIO_write_ex(dispatch); 90 | break; 91 | case OSSL_FUNC_BIO_UP_REF: 92 | core_bio_up_ref = OSSL_FUNC_BIO_up_ref(dispatch); 93 | break; 94 | case OSSL_FUNC_BIO_FREE: 95 | core_bio_free = OSSL_FUNC_BIO_free(dispatch); 96 | break; 97 | case OSSL_FUNC_BIO_PUTS: 98 | core_bio_puts = OSSL_FUNC_BIO_puts(dispatch); 99 | break; 100 | case OSSL_FUNC_BIO_GETS: 101 | core_bio_gets = OSSL_FUNC_BIO_gets(dispatch); 102 | break; 103 | case OSSL_FUNC_BIO_CTRL: 104 | core_bio_ctrl = OSSL_FUNC_BIO_ctrl(dispatch); 105 | break; 106 | } 107 | } 108 | } 109 | 110 | BIO_METHOD *p_scossl_bio_init() 111 | { 112 | BIO_METHOD *coreBioMeth = BIO_meth_new(BIO_TYPE_CORE_TO_PROV, "SCOSSL BIO to core filter"); 113 | 114 | if (coreBioMeth != NULL && 115 | (!BIO_meth_set_read_ex(coreBioMeth, p_scossl_bio_core_read_ex) || 116 | !BIO_meth_set_write_ex(coreBioMeth, p_scossl_bio_core_write_ex) || 117 | !BIO_meth_set_create(coreBioMeth, p_scossl_bio_core_create) || 118 | !BIO_meth_set_destroy(coreBioMeth, p_scossl_bio_core_destroy) || 119 | !BIO_meth_set_gets(coreBioMeth, p_scossl_bio_core_gets) || 120 | !BIO_meth_set_puts(coreBioMeth, p_scossl_bio_core_puts) || 121 | !BIO_meth_set_ctrl(coreBioMeth, p_scossl_bio_core_ctrl))) 122 | { 123 | BIO_meth_free(coreBioMeth); 124 | coreBioMeth = NULL; 125 | } 126 | 127 | return coreBioMeth; 128 | } 129 | 130 | _Use_decl_annotations_ 131 | BIO *p_scossl_bio_new_from_core_bio(SCOSSL_PROVCTX *provctx, OSSL_CORE_BIO *coreBio) 132 | { 133 | BIO *bio; 134 | 135 | if (provctx == NULL || provctx->coreBioMeth == NULL) 136 | { 137 | return NULL; 138 | } 139 | 140 | if ((bio = BIO_new_ex(provctx->libctx, provctx->coreBioMeth)) != NULL) 141 | { 142 | if (core_bio_up_ref == NULL || 143 | !core_bio_up_ref(coreBio)) 144 | { 145 | BIO_free(bio); 146 | return NULL; 147 | } 148 | 149 | BIO_set_data(bio, coreBio); 150 | } 151 | 152 | return bio; 153 | } 154 | 155 | #ifdef __cplusplus 156 | } 157 | #endif -------------------------------------------------------------------------------- /SymCryptProvider/src/p_scossl_bio.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include "p_scossl_base.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | void p_scossl_set_core_bio(_In_ const OSSL_DISPATCH *dispatch); 12 | BIO_METHOD *p_scossl_bio_init(); 13 | BIO *p_scossl_bio_new_from_core_bio(_In_ SCOSSL_PROVCTX *provctx, _In_ OSSL_CORE_BIO *coreBio); 14 | 15 | #ifdef __cplusplus 16 | } 17 | #endif -------------------------------------------------------------------------------- /SymCryptProvider/src/p_scossl_ecc.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | #include "p_scossl_base.h" 5 | #ifdef KEYSINUSE_ENABLED 6 | #include "p_scossl_keysinuse.h" 7 | #endif 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | typedef struct { 14 | OSSL_LIB_CTX *libctx; 15 | BOOL initialized; 16 | PSYMCRYPT_ECKEY key; 17 | PCSYMCRYPT_ECURVE curve; 18 | BOOL isX25519; 19 | // RFC7748 dictates that to decode the x25519 private key, we need to 20 | // 1. Set the three least significant bits of the MSB to 0 21 | // 2. Set the most significant bit of the LSB to 0 22 | // 3. Set the second most significant bit of the LSB to 1 23 | // SymCrypt expects the operation to be applied to the private 24 | // key before import. In order to preserve the original key data 25 | // for export, the transformed bits are stored here. The position 26 | // of the modified bits in the MSB and LSB differ, so we can use 27 | // a single byte. 28 | BYTE modifiedPrivateBits; 29 | // Not used for crypto operations. Only used in import/export 30 | // to let the provider handling encoding/decoding whether to 31 | // include the public key. 32 | int includePublic; 33 | point_conversion_form_t conversionFormat; 34 | 35 | #ifdef KEYSINUSE_ENABLED 36 | BOOL isImported; 37 | CRYPTO_RWLOCK *keysinuseLock; 38 | SCOSSL_PROV_KEYSINUSE_INFO *keysinuseInfo; 39 | #endif 40 | } SCOSSL_ECC_KEY_CTX; 41 | 42 | SCOSSL_ECC_KEY_CTX *p_scossl_ecc_new_ctx(_In_ SCOSSL_PROVCTX *provctx); 43 | void p_scossl_ecc_free_ctx(_Inout_ SCOSSL_ECC_KEY_CTX *keyCtx); 44 | SCOSSL_ECC_KEY_CTX *p_scossl_ecc_dup_ctx(_In_ SCOSSL_ECC_KEY_CTX *keyCtx, int selection); 45 | 46 | SCOSSL_STATUS p_scossl_ecc_set_group(_Inout_ SCOSSL_ECC_KEY_CTX *keyCtx, _In_ const char *groupName); 47 | 48 | SCOSSL_STATUS p_scossl_ecc_gen(_Inout_ SCOSSL_ECC_KEY_CTX *keyCtx); 49 | 50 | SIZE_T p_scossl_ecc_get_max_result_size(_In_ SCOSSL_ECC_KEY_CTX *keyCtx, BOOL isEcdh); 51 | SIZE_T p_scossl_ecc_get_encoded_key_size(_In_ SCOSSL_ECC_KEY_CTX *keyCtx, int selection); 52 | SCOSSL_STATUS p_scossl_ecc_get_encoded_key(_In_ SCOSSL_ECC_KEY_CTX *keyCtx, int selection, 53 | _Out_writes_bytes_(*pcbKey) PBYTE *ppbKey, _Out_ SIZE_T *pcbKey); 54 | SCOSSL_STATUS p_scossl_ecc_set_encoded_key(_In_ SCOSSL_ECC_KEY_CTX *keyCtx, 55 | _In_reads_bytes_opt_(cbEncodedPublicKey) PCBYTE pbEncodedPublicKey, SIZE_T cbEncodedPublicKey, 56 | _In_reads_bytes_opt_(cbEncodedPrivateKey) PCBYTE pbEncodedPrivateKey, SIZE_T cbEncodedPrivateKey); 57 | 58 | #ifdef KEYSINUSE_ENABLED 59 | void p_scossl_ecc_init_keysinuse(_In_ SCOSSL_ECC_KEY_CTX *keyCtx); 60 | void p_scossl_ecc_reset_keysinuse(_In_ SCOSSL_ECC_KEY_CTX *keyCtx); 61 | #endif 62 | 63 | #ifdef __cplusplus 64 | } 65 | #endif -------------------------------------------------------------------------------- /SymCryptProvider/src/p_scossl_keysinuse.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | // This structure is refcounted. The key object this is associated with may 12 | // be freed, but logging events may be pending according to the logging backoff. 13 | // This is created on the first sign/decrypt init using the key, and destroyed 14 | // with the key context in the key management interface. 15 | typedef struct 16 | { 17 | time_t firstLogTime; 18 | time_t lastLogTime; 19 | UINT32 signCounter; 20 | UINT32 decryptCounter; 21 | // The first 32 bytes of the SHA256 hash of the encoded public key. 22 | // Use the same encoding rules as the subjectPublicKey field of a certificate 23 | // (PKCS#1 format for RSA, octet string for ECDSA) 24 | char keyIdentifier[SYMCRYPT_SHA256_RESULT_SIZE + 1]; 25 | BOOL logPending; 26 | INT32 refCount; 27 | CRYPTO_RWLOCK *lock; 28 | } SCOSSL_PROV_KEYSINUSE_INFO; 29 | 30 | // Setup/teardown 31 | void p_scossl_keysinuse_init(); 32 | void p_scossl_keysinuse_teardown(); 33 | BOOL p_scossl_keysinuse_running(); 34 | 35 | // Configuration 36 | // If an invalid config value is passed, the respective default is used instead 37 | void p_scossl_keysinuse_set_logging_id(_In_ const char *id); 38 | void p_scossl_keysinuse_set_max_file_size(off_t size); 39 | void p_scossl_keysinuse_set_logging_delay(INT64 delay); 40 | 41 | // KeysInUse info management 42 | SCOSSL_PROV_KEYSINUSE_INFO *p_scossl_keysinuse_info_new(_In_reads_bytes_(cbPublicKey) PBYTE pbPublicKey, SIZE_T cbPublicKey); 43 | void p_scossl_keysinuse_info_free(_Inout_ SCOSSL_PROV_KEYSINUSE_INFO *keysinuseInfo); 44 | SCOSSL_STATUS p_scossl_keysinuse_upref(_Inout_ SCOSSL_PROV_KEYSINUSE_INFO *keysinuseInfo, _Out_ INT32 *refOut); 45 | SCOSSL_STATUS p_scossl_keysinuse_downref(_Inout_ SCOSSL_PROV_KEYSINUSE_INFO *keysinuseInfo, _Out_ INT32 *refOut); 46 | 47 | // Usage tracking 48 | void p_scossl_keysinuse_on_sign(_In_ SCOSSL_PROV_KEYSINUSE_INFO *keysinuseInfo); 49 | void p_scossl_keysinuse_on_decrypt(_In_ SCOSSL_PROV_KEYSINUSE_INFO *keysinuseInfo); 50 | 51 | #ifdef __cplusplus 52 | } 53 | #endif -------------------------------------------------------------------------------- /SymCryptProvider/src/p_scossl_names.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #pragma once 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | // 12 | // Provider algorithm names 13 | // 14 | 15 | // Digests 16 | #define SCOSSL_ALG_NAME_MD5 SN_md5":SSL3-MD5:1.2.840.113549.2.5" 17 | #define SCOSSL_ALG_NAME_SHA1 SN_sha1":SHA-1:SSL3-SHA1:1.3.14.3.2.26" 18 | #define SCOSSL_ALG_NAME_SHA224 SN_sha224":SHA2-224:SHA-224:2.16.840.1.101.3.4.2.4" 19 | #define SCOSSL_ALG_NAME_SHA256 SN_sha256":SHA2-256:SHA-256:2.16.840.1.101.3.4.2.1" 20 | #define SCOSSL_ALG_NAME_SHA384 SN_sha384":SHA2-384:SHA-384:2.16.840.1.101.3.4.2.2" 21 | #define SCOSSL_ALG_NAME_SHA512 SN_sha512":SHA2-512:SHA-512:2.16.840.1.101.3.4.2.3" 22 | #define SCOSSL_ALG_NAME_SHA512_224 SN_sha512_224":SHA2-512/224:SHA-512/224:2.16.840.1.101.3.4.2.5" 23 | #define SCOSSL_ALG_NAME_SHA512_256 SN_sha512_256":SHA2-512/256:SHA-512/256:2.16.840.1.101.3.4.2.6" 24 | #define SCOSSL_ALG_NAME_SHA3_224 SN_sha3_224":2.16.840.1.101.3.4.2.7" 25 | #define SCOSSL_ALG_NAME_SHA3_256 SN_sha3_256":2.16.840.1.101.3.4.2.8" 26 | #define SCOSSL_ALG_NAME_SHA3_384 SN_sha3_384":2.16.840.1.101.3.4.2.9" 27 | #define SCOSSL_ALG_NAME_SHA3_512 SN_sha3_512":2.16.840.1.101.3.4.2.10" 28 | #define SCOSSL_ALG_NAME_SHAKE128 SN_shake128":SHAKE-128:2.16.840.1.101.3.4.2.11" 29 | #define SCOSSL_ALG_NAME_SHAKE256 SN_shake256":SHAKE-256:2.16.840.1.101.3.4.2.12" 30 | #define SCOSSL_ALG_NAME_CSHAKE128 "CSHAKE-128:CSHAKE128" 31 | #define SCOSSL_ALG_NAME_CSHAKE256 "CSHAKE-256:CSHAKE256" 32 | 33 | // Ciphers 34 | #define SCOSSL_ALG_NAME_AES_128_CBC SN_aes_128_cbc":AES128:2.16.840.1.101.3.4.1.2" 35 | #define SCOSSL_ALG_NAME_AES_192_CBC SN_aes_192_cbc":AES192:2.16.840.1.101.3.4.1.22" 36 | #define SCOSSL_ALG_NAME_AES_256_CBC SN_aes_256_cbc":AES256:2.16.840.1.101.3.4.1.42" 37 | #define SCOSSL_ALG_NAME_AES_128_ECB SN_aes_128_ecb":2.16.840.1.101.3.4.1.1" 38 | #define SCOSSL_ALG_NAME_AES_192_ECB SN_aes_192_ecb":2.16.840.1.101.3.4.1.21" 39 | #define SCOSSL_ALG_NAME_AES_256_ECB SN_aes_256_ecb":2.16.840.1.101.3.4.1.41" 40 | #define SCOSSL_ALG_NAME_AES_128_CFB SN_aes_128_cfb128":2.16.840.1.101.3.4.1.4" 41 | #define SCOSSL_ALG_NAME_AES_192_CFB SN_aes_192_cfb128":2.16.840.1.101.3.4.1.24" 42 | #define SCOSSL_ALG_NAME_AES_256_CFB SN_aes_256_cfb128":2.16.840.1.101.3.4.1.44" 43 | #define SCOSSL_ALG_NAME_AES_128_CFB8 SN_aes_128_cfb8 44 | #define SCOSSL_ALG_NAME_AES_192_CFB8 SN_aes_192_cfb8 45 | #define SCOSSL_ALG_NAME_AES_256_CFB8 SN_aes_256_cfb8 46 | #define SCOSSL_ALG_NAME_AES_128_GCM SN_aes_128_gcm":AES-128-GCM:2.16.840.1.101.3.4.1.6" 47 | #define SCOSSL_ALG_NAME_AES_192_GCM SN_aes_192_gcm":AES-192-GCM:2.16.840.1.101.3.4.1.26" 48 | #define SCOSSL_ALG_NAME_AES_256_GCM SN_aes_256_gcm":AES-256-GCM:2.16.840.1.101.3.4.1.46" 49 | #define SCOSSL_ALG_NAME_AES_128_CCM SN_aes_128_ccm":AES-128-CCM:2.16.840.1.101.3.4.1.7" 50 | #define SCOSSL_ALG_NAME_AES_192_CCM SN_aes_192_ccm":AES-192-CCM:2.16.840.1.101.3.4.1.27" 51 | #define SCOSSL_ALG_NAME_AES_256_CCM SN_aes_256_ccm":AES-256-CCM:2.16.840.1.101.3.4.1.47" 52 | #define SCOSSL_ALG_NAME_AES_128_XTS SN_aes_128_xts":1.3.111.2.1619.0.1.1" 53 | #define SCOSSL_ALG_NAME_AES_256_XTS SN_aes_256_xts":1.3.111.2.1619.0.1.2" 54 | 55 | // MAC 56 | #define SCOSSL_ALG_NAME_CMAC SN_cmac 57 | #define SCOSSL_ALG_NAME_HMAC SN_hmac 58 | #define SCOSSL_ALG_NAME_KMAC128 SN_kmac128":KMAC-128:KMAC128:2.16.840.1.101.3.4.2.19" 59 | #define SCOSSL_ALG_NAME_KMAC256 SN_kmac256":KMAC-256:KMAC256:2.16.840.1.101.3.4.2.20" 60 | 61 | // KDF 62 | #define SCOSSL_ALG_NAME_HKDF SN_hkdf 63 | #define SCOSSL_ALG_NAME_KBKDF "KBKDF" 64 | #define SCOSSL_ALG_NAME_PBKDF2 LN_id_pbkdf2":1.2.840.113549.1.5.12" 65 | #define SCOSSL_ALG_NAME_SRTPKDF "SRTPKDF" 66 | #define SCOSSL_ALG_NAME_SRTCPKDF "SRTCPKDF" 67 | #define SCOSSL_ALG_NAME_SSHKDF SN_sshkdf 68 | #define SCOSSL_ALG_NAME_SSKDF SN_sskdf 69 | #define SCOSSL_ALG_NAME_TLS1_PRF SN_tls1_prf 70 | 71 | // Rand 72 | #define SCOSSL_ALG_NAME_CTR_DBG "CTR-DRBG" 73 | 74 | // Key management 75 | #define SCOSSL_ALG_NAME_EC SN_X9_62_id_ecPublicKey":EC:1.2.840.10045.2.1" 76 | #define SCOSSL_ALG_NAME_RSA_PSS SN_rsassaPss":RSA-PSS:1.2.840.113549.1.1.10" 77 | 78 | // Key exchange 79 | #define SCOSSL_ALG_NAME_DH LN_dhKeyAgreement":DH:1.2.840.113549.1.3.1" 80 | #define SCOSSL_ALG_NAME_ECDH "ECDH" 81 | #define SCOSSL_ALG_NAME_X25519 SN_X25519":1.3.101.110" 82 | 83 | // Signature 84 | #define SCOSSL_ALG_NAME_RSA SN_rsa":"LN_rsaEncryption":1.2.840.113549.1.1.1" 85 | #define SCOSSL_ALG_NAME_ECDSA "ECDSA" 86 | 87 | // Key encapsulation 88 | #define SCOSSL_ALG_NAME_MLKEM "MLKEM" 89 | #define SCOSSL_ALG_NAME_MLKEM_DECODER SCOSSL_ALG_NAME_MLKEM":" \ 90 | SCOSSL_SN_MLKEM512":" \ 91 | SCOSSL_OID_MLKEM512":" \ 92 | SCOSSL_SN_MLKEM768":" \ 93 | SCOSSL_OID_MLKEM768":" \ 94 | SCOSSL_SN_MLKEM1024":" \ 95 | SCOSSL_OID_MLKEM1024 96 | 97 | #ifdef __cplusplus 98 | } 99 | #endif -------------------------------------------------------------------------------- /SymCryptProvider/src/p_scossl_rand.c: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #include "scossl_helpers.h" 10 | 11 | #define SCOSSL_DRBG_STRENGTH 256 12 | #define SCOSSL_DRBG_MAX_REQUEST_SIZE (1 << 16) 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | 18 | static const BYTE dummy_scossl_ctx = 0; 19 | 20 | static const OSSL_PARAM gettable_ctx_param_types[] = { 21 | OSSL_PARAM_int(OSSL_RAND_PARAM_STATE, NULL), 22 | OSSL_PARAM_uint(OSSL_RAND_PARAM_STRENGTH, NULL), 23 | OSSL_PARAM_size_t(OSSL_RAND_PARAM_MAX_REQUEST, NULL), 24 | OSSL_PARAM_END}; 25 | 26 | // All state is maintained inside SymCrypt, but newctx and 27 | // freectx are expected. These do nothing in the SymCrypt provider 28 | static void *p_scossl_rand_newctx(ossl_unused void *provctx, 29 | ossl_unused void *parent, 30 | ossl_unused const OSSL_DISPATCH *parent_calls) 31 | { 32 | return (void *)&dummy_scossl_ctx; 33 | } 34 | 35 | static void p_scossl_rand_freectx(ossl_unused void *ctx){} 36 | 37 | // RNG state is internally managed by SymCrypt. This function is 38 | // required, but does not actually instantiate SymCrypt's RNG state 39 | static SCOSSL_STATUS p_scossl_rand_instantiate(ossl_unused void *ctx, 40 | unsigned int strength, 41 | int prediction_resistance, 42 | _In_reads_bytes_opt_(addin_len) const unsigned char *addin, size_t addin_len, 43 | ossl_unused const OSSL_PARAM params[]) 44 | { 45 | if (strength > SCOSSL_DRBG_STRENGTH || prediction_resistance) 46 | { 47 | return SCOSSL_FAILURE; 48 | } 49 | 50 | if (addin_len > 0) 51 | { 52 | SymCryptProvideEntropy(addin, addin_len); 53 | } 54 | 55 | return SCOSSL_SUCCESS; 56 | } 57 | 58 | // RNG state is internally managed by SymCrypt. This function is 59 | // required, but does not actually uninstantiate SymCrypt's RNG state. 60 | // RNG is uninstantiated on SymCrypt unload 61 | SCOSSL_STATUS p_scossl_rand_uninstantiate(ossl_unused void *ctx) 62 | { 63 | return SCOSSL_SUCCESS; 64 | } 65 | 66 | static SCOSSL_STATUS p_scossl_rand_generate(ossl_unused void *ctx, 67 | _Out_writes_bytes_(outlen) unsigned char *out, size_t outlen, 68 | ossl_unused unsigned int strength, 69 | ossl_unused int prediction_resistance, 70 | _In_reads_bytes_opt_(addin_len) const unsigned char *addin, size_t addin_len) 71 | { 72 | if (addin_len > 0) 73 | { 74 | SymCryptProvideEntropy(addin, addin_len); 75 | } 76 | 77 | SymCryptRandom(out, outlen); 78 | return SCOSSL_SUCCESS; 79 | } 80 | 81 | static SCOSSL_STATUS p_scossl_rand_reseed(ossl_unused void *ctx, 82 | ossl_unused int prediction_resistance, 83 | ossl_unused const unsigned char *ent, ossl_unused size_t ent_len, 84 | _In_reads_bytes_opt_(addin_len) const unsigned char *addin, size_t addin_len) 85 | { 86 | SymCryptProvideEntropy(addin, addin_len); 87 | return SCOSSL_SUCCESS; 88 | } 89 | 90 | // SymCrypt internally mangages locking, so the provider does not need 91 | // to. This function is required but does nothing 92 | static SCOSSL_STATUS p_scossl_rand_enable_locking(ossl_unused void *ctx) 93 | { 94 | return SCOSSL_SUCCESS; 95 | } 96 | 97 | static const OSSL_PARAM *p_scossl_rand_gettable_ctx_params(ossl_unused void *ctx, ossl_unused void *provctx) 98 | { 99 | return gettable_ctx_param_types; 100 | } 101 | 102 | static SCOSSL_STATUS p_scossl_rand_get_ctx_params(ossl_unused void *ctx, _Inout_ OSSL_PARAM params[]) 103 | { 104 | OSSL_PARAM *p = NULL; 105 | 106 | // State managed by symcrypt module 107 | p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_STATE); 108 | if (p != NULL && !OSSL_PARAM_set_int(p, 1)) 109 | { 110 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); 111 | return SCOSSL_FAILURE; 112 | } 113 | p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_STRENGTH); 114 | if (p != NULL && !OSSL_PARAM_set_uint(p, SCOSSL_DRBG_STRENGTH)) 115 | { 116 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); 117 | return SCOSSL_FAILURE; 118 | } 119 | p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_MAX_REQUEST); 120 | if (p != NULL && !OSSL_PARAM_set_size_t(p, SCOSSL_DRBG_MAX_REQUEST_SIZE)) 121 | { 122 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); 123 | return SCOSSL_FAILURE; 124 | } 125 | return SCOSSL_SUCCESS; 126 | } 127 | 128 | const OSSL_DISPATCH p_scossl_rand_functions[] = { 129 | {OSSL_FUNC_RAND_NEWCTX, (void (*)(void))p_scossl_rand_newctx}, 130 | {OSSL_FUNC_RAND_FREECTX, (void (*)(void))p_scossl_rand_freectx}, 131 | {OSSL_FUNC_RAND_INSTANTIATE, (void (*)(void))p_scossl_rand_instantiate}, 132 | {OSSL_FUNC_RAND_UNINSTANTIATE, (void (*)(void))p_scossl_rand_uninstantiate}, 133 | {OSSL_FUNC_RAND_GENERATE, (void (*)(void))p_scossl_rand_generate}, 134 | {OSSL_FUNC_RAND_RESEED, (void (*)(void))p_scossl_rand_reseed}, 135 | {OSSL_FUNC_RAND_ENABLE_LOCKING, (void (*)(void))p_scossl_rand_enable_locking}, 136 | {OSSL_FUNC_RAND_GETTABLE_CTX_PARAMS, (void (*)(void))p_scossl_rand_gettable_ctx_params}, 137 | {OSSL_FUNC_RAND_GET_CTX_PARAMS, (void (*)(void))p_scossl_rand_get_ctx_params}, 138 | {0, NULL}}; 139 | 140 | #ifdef __cplusplus 141 | } 142 | #endif -------------------------------------------------------------------------------- /SymCryptProvider/src/p_scossl_rsa.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) Microsoft Corporation. Licensed under the MIT license. 3 | // 4 | 5 | #include "scossl_helpers.h" 6 | #ifdef KEYSINUSE_ENABLED 7 | #include "p_scossl_keysinuse.h" 8 | #endif 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | typedef struct 15 | { 16 | const OSSL_ITEM *mdInfo; 17 | const OSSL_ITEM *mgf1MdInfo; 18 | int cbSaltMin; 19 | } SCOSSL_RSA_PSS_RESTRICTIONS; 20 | 21 | typedef struct 22 | { 23 | OSSL_LIB_CTX *libctx; 24 | BOOL initialized; 25 | PSYMCRYPT_RSAKEY key; 26 | UINT keyType; 27 | SCOSSL_RSA_PSS_RESTRICTIONS *pssRestrictions; 28 | 29 | #ifdef KEYSINUSE_ENABLED 30 | BOOL isImported; 31 | CRYPTO_RWLOCK *keysinuseLock; 32 | SCOSSL_PROV_KEYSINUSE_INFO *keysinuseInfo; 33 | #endif 34 | } SCOSSL_PROV_RSA_KEY_CTX; 35 | 36 | const OSSL_ITEM *p_scossl_rsa_get_supported_md(_In_ OSSL_LIB_CTX *libctx, UINT padding, 37 | _In_ const char *mdname, _In_ const char *propq, 38 | _Out_opt_ EVP_MD **md); 39 | 40 | SCOSSL_STATUS p_scossl_rsa_pss_restrictions_from_params(_In_ OSSL_LIB_CTX *libctx, _In_ const OSSL_PARAM params[], 41 | _Out_ SCOSSL_RSA_PSS_RESTRICTIONS **pPssRestrictions); 42 | 43 | SCOSSL_STATUS p_scossl_rsa_pss_restrictions_to_params(_In_ const SCOSSL_RSA_PSS_RESTRICTIONS *pssRestrictions, 44 | _Inout_ OSSL_PARAM_BLD *bld); 45 | 46 | void p_scossl_rsa_pss_restrictions_get_defaults(_Inout_ SCOSSL_RSA_PSS_RESTRICTIONS *pssRestrictions); 47 | 48 | #ifdef KEYSINUSE_ENABLED 49 | SCOSSL_STATUS p_scossl_rsa_get_encoded_public_key(_In_ PCSYMCRYPT_RSAKEY key, 50 | _Inout_ PBYTE *ppbEncodedKey, _Inout_ SIZE_T *pcbEncodedKey); 51 | void p_scossl_rsa_init_keysinuse(_In_ SCOSSL_PROV_RSA_KEY_CTX *keyCtx); 52 | void p_scossl_rsa_reset_keysinuse(_In_ SCOSSL_PROV_RSA_KEY_CTX *keyCtx); 53 | #endif 54 | 55 | #ifdef __cplusplus 56 | } 57 | #endif -------------------------------------------------------------------------------- /SymCryptProvider/symcrypt_prov.cnf: -------------------------------------------------------------------------------- 1 | # The SymCrypt provider needs to be registered with libcrypto, 2 | # either by config or with OSSL_PROVIDER_load. The provider can 3 | # be disabled by commenting out or removing "activate = 1". The 4 | # value assigned does not matter, and the provider will be 5 | # activated as long as the "activate" key is present. 6 | 7 | [symcrypt_prov_sect] 8 | activate = 1 9 | identity = symcryptprovider 10 | keysinuse = keysinuse_sect 11 | 12 | [keysinuse_sect] 13 | enabled = 0 14 | max_file_size = 5KB 15 | logging_delay_seconds = 3600 -------------------------------------------------------------------------------- /cmake-toolchain/LinuxUserMode-AMD64.cmake: -------------------------------------------------------------------------------- 1 | # This toolchain file configures CMake options for Linux User Mode AMD64 compilation with CPU optimizations. 2 | # To use the toolchain file, run cmake .. -DCMAKE_TOOLCHAIN_FILE="cmake-toolchain/LinuxUserMode-AMD64.cmake" 3 | 4 | # Set CMake variables that subsequent CMake scripts can check against 5 | set(CMAKE_SYSTEM_NAME Linux) 6 | set(CMAKE_SYSTEM_PROCESSOR AMD64) 7 | 8 | # Define _AMD64_ to set up the correct SymCrypt macros, e.g. SYMCRYPT_CPU_AMD64 9 | add_compile_options(-D_AMD64_) 10 | if (CMAKE_BUILD_TYPE MATCHES Release|RelWithDebInfo) 11 | add_compile_options(-O3) 12 | endif() 13 | 14 | # Enable a baseline of features for the compiler to support everywhere 15 | # Other than for SSSE3 we do not expect the compiler to generate these instructions anywhere other than with intrinsics 16 | # 17 | # We cannot globally enable AVX and later, as we need to keep use of these instructions behind CPU detection, and the 18 | # instructions are definitely useful enough for a smart compiler to use them in C code (i.e. in memcpy) 19 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mssse3 -mxsave -maes -mpclmul -msha -mrdrnd -mrdseed") 20 | 21 | set(CMAKE_ASM_FLAGS "-x assembler-with-cpp") -------------------------------------------------------------------------------- /cmake-toolchain/LinuxUserMode-ARM.cmake: -------------------------------------------------------------------------------- 1 | # This toolchain file configures CMake options for Linux User Mode ARM compilation with CPU optimizations. 2 | # To use the toolchain file, run cmake .. -DCMAKE_TOOLCHAIN_FILE="cmake-toolchain/LinuxUserMode-ARM.cmake" 3 | 4 | # Set CMake variables that subsequent CMake scripts can check against 5 | set(CMAKE_SYSTEM_NAME Linux) 6 | set(CMAKE_SYSTEM_PROCESSOR ARM) 7 | 8 | # Point compiler sysroot to cross compilation toolchain when cross compiling 9 | if(NOT CMAKE_HOST_SYSTEM_PROCESSOR MATCHES armv8l|ARM$|ARM32|aarch32 AND NOT SCOSSL_USE_DEFAULT_COMPILER) 10 | message(STATUS "Using cross compilation toolchain") 11 | 12 | set(TARGET_TRIPLE arm-linux-gnueabihf) 13 | 14 | set(CMAKE_ASM_COMPILER_TARGET ${TARGET_TRIPLE}) 15 | set(CMAKE_C_COMPILER ${TARGET_TRIPLE}-gcc) 16 | set(CMAKE_C_COMPILER_TARGET ${TARGET_TRIPLE}) 17 | set(CMAKE_CXX_COMPILER ${TARGET_TRIPLE}-g++) 18 | set(CMAKE_CXX_COMPILER_TARGET ${TARGET_TRIPLE}) 19 | 20 | # C/C++ toolchain (installed on Ubuntu using apt-get gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf) 21 | set(CMAKE_SYSROOT_COMPILE /usr/${TARGET_TRIPLE}) 22 | 23 | find_path(CXX_CROSS_INCLUDE_DIR NAMES ${TARGET_TRIPLE} PATHS /usr/${TARGET_TRIPLE}/include/c++/ PATH_SUFFIXES 15 14 13 12 11 10 9 8 7 6 5 NO_DEFAULT_PATH) 24 | add_compile_options(-I${CXX_CROSS_INCLUDE_DIR}/${TARGET_TRIPLE}) 25 | endif() 26 | 27 | add_compile_options(-D_ARM_) 28 | if (CMAKE_BUILD_TYPE MATCHES Release|RelWithDebInfo) 29 | add_compile_options(-O3) 30 | endif() -------------------------------------------------------------------------------- /cmake-toolchain/LinuxUserMode-ARM64.cmake: -------------------------------------------------------------------------------- 1 | # This toolchain file configures CMake options for Linux User Mode ARM64 compilation with CPU optimizations. 2 | # To use the toolchain file, run cmake .. -DCMAKE_TOOLCHAIN_FILE="cmake-toolchain/LinuxUserMode-ARM64.cmake" 3 | 4 | # Set CMake variables that subsequent CMake scripts can check against 5 | set(CMAKE_SYSTEM_NAME Linux) 6 | set(CMAKE_SYSTEM_PROCESSOR ARM64) 7 | 8 | # Point clang sysroot to cross compilation toolchain when cross compiling 9 | if(NOT CMAKE_HOST_SYSTEM_PROCESSOR MATCHES ARM64|aarch64 AND NOT SCOSSL_USE_DEFAULT_COMPILER) 10 | message(STATUS "Using cross compilation toolchain") 11 | 12 | set(TARGET_TRIPLE aarch64-linux-gnu) 13 | 14 | # Currently only use clang as it makes cross-compilation easier 15 | set(CMAKE_ASM_COMPILER_TARGET ${TARGET_TRIPLE}) 16 | set(CMAKE_C_COMPILER clang) 17 | set(CMAKE_C_COMPILER_TARGET ${TARGET_TRIPLE}) 18 | set(CMAKE_CXX_COMPILER clang++) 19 | set(CMAKE_CXX_COMPILER_TARGET ${TARGET_TRIPLE}) 20 | 21 | # C/C++ toolchain (installed on Ubuntu using apt-get gcc-aarch64-linux-gnu g++-aarch64-linux-gnu) 22 | set(CMAKE_SYSROOT_COMPILE /usr/${TARGET_TRIPLE}) 23 | 24 | # We would expect setting SYSROOT to be sufficient for clang to cross-compile with the gcc-aarch64-linux-gnu 25 | # toolchain, but it seems that this misses a few key header files for C++... 26 | # Hacky solution which seems to work for Ubuntu + clang: 27 | # Get CMake to find the appropriate include directory and explicitly include it 28 | # Seems like there should be a better way to install cross-compilation tools, or specify search paths to clang 29 | find_path(CXX_CROSS_INCLUDE_DIR NAMES ${TARGET_TRIPLE} PATHS /usr/${TARGET_TRIPLE}/include/c++/ PATH_SUFFIXES 15 14 13 12 11 10 9 8 7 6 5 NO_DEFAULT_PATH) 30 | add_compile_options(-I${CXX_CROSS_INCLUDE_DIR}/${TARGET_TRIPLE}) 31 | endif() 32 | 33 | # Define _ARM64_ to set up the correct SymCrypt macros, e.g. SYMCRYPT_CPU_ARM64 34 | add_compile_options(-D_ARM64_) 35 | if (CMAKE_BUILD_TYPE MATCHES Release|RelWithDebInfo) 36 | add_compile_options(-O3) 37 | endif() --------------------------------------------------------------------------------