diff --git a/EvpTestRecipes/3.5/evppkey_ecdsa_sigalg.txt b/EvpTestRecipes/3.5/evppkey_ecdsa_sigalg.txt new file mode 100644 index 00000000..3b541699 --- /dev/null +++ b/EvpTestRecipes/3.5/evppkey_ecdsa_sigalg.txt @@ -0,0 +1,155 @@ +# +# Copyright 2024 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +# Tests start with one of these keywords +# Cipher Decrypt Derive Digest Encoding KDF MAC PBE +# PrivPubKeyPair Sign Verify VerifyRecover +# and continue until a blank line. Lines starting with a pound sign are ignored. +# The keyword Availablein must appear before the test name if needed. + +# Public key algorithm tests + +# Private keys used for PKEY operations. + +# EC P-256 key + +PrivateKey=P-256 +-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgiocvtiiTxNH/xbnw ++RdYBp+DUuCPoFpJ+NuSbLVyhyWhRANCAAQsFQ9CnOcPIWwlLPXgYs4fY5zV0WXH ++JQkBywnGX14szuSDpXNtmTpkNzwz+oNlOKo5q+dDlgFbmUxBJJbn+bJ +-----END PRIVATE KEY----- + +# EC public key for above + +PublicKey=P-256-PUBLIC +-----BEGIN PUBLIC KEY----- +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAELBUPQpznDyFsJSz14GLOH2Oc1dFl +x/iUJAcsJxl9eLM7kg6VzbZk6ZDc8M/qDZTiqOavnQ5YBW5lMQSSW5/myQ== +-----END PUBLIC KEY----- + +PrivPubKeyPair = P-256:P-256-PUBLIC + +Title = ECDSA tests + +Verify = ECDSA-SHA1:P-256-PUBLIC +Input = "0123456789ABCDEF1234" +Output = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec8 + +# Digest too long +Verify = ECDSA-SHA1:P-256-PUBLIC +Input = "0123456789ABCDEF12345" +Output = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec8 +Result = VERIFY_ERROR + +# Digest too short +Verify = ECDSA-SHA1:P-256-PUBLIC +Input = "0123456789ABCDEF123" +Output = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec8 +Result = VERIFY_ERROR + +# Digest invalid +Verify = ECDSA-SHA1:P-256-PUBLIC +Input = "0123456789ABCDEF1235" +Output = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec8 +Result = VERIFY_ERROR + +# Invalid signature +Verify = ECDSA-SHA1:P-256-PUBLIC +Input = "0123456789ABCDEF1234" +Output = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec7 +Result = VERIFY_ERROR + +# Garbage after signature +Verify = ECDSA-SHA1:P-256-PUBLIC +Input = "0123456789ABCDEF1234" +Output = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec800 +Result = VERIFY_ERROR + +# BER signature +Verify = ECDSA-SHA1:P-256-PUBLIC +Input = "0123456789ABCDEF1234" +Output = 3080022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec80000 +Result = VERIFY_ERROR + +Verify = ECDSA-SHA1:P-256-PUBLIC +Input = "0123456789ABCDEF1234" +Output = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec8 + +Title = Sign-Message and Verify-Message + +Verify-Message-Public = ECDSA-SHA256:P-256-PUBLIC +Input = "Hello World" +Output = 3046022100e7515177ec3817b77a4a94066ab3070817b7aa9d44a8a09f040da250116e8972022100ba59b0f631258e59a9026be5d84f60685f4cf22b9165a0c2736d5c21c8ec1862 + +PublicKey=P-384-PUBLIC +-----BEGIN PUBLIC KEY----- +MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAES/TlL5WEJ+u1kV+4yVlVUbTTo/2rZ7rd +nWwwk/QlukNjDfcfQvDrfOqpTZ9kSKhd0wMxWIJJ/S/cCzCex+2EgbwW8ngAwT19 +twD8guGxyFRaoMDTtW47/nifwYqRaIfC +-----END PUBLIC KEY----- + +Verify-Message-Public = ECDSA-SHA384:P-384-PUBLIC +Input = "123400" +Output = 304d0218389cb27e0bc8d21fa7e5f24cb74f58851313e696333ad68b023100ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52970 + +# Oneshot tests +Verify-Message-Public = ECDSA-SHA256:P-256-PUBLIC +Input = "Hello World" +Output = 3046022100e7515177ec3817b77a4a94066ab3070817b7aa9d44a8a09f040da250116e8972022100ba59b0f631258e59a9026be5d84f60685f4cf22b9165a0c2736d5c21c8ec1862 + +# Test that mdsize != tbssize fails +Sign = ECDSA-SHA256:P-256 +Input = "0123456789ABCDEF1234" +Result = KEYOP_ERROR + +PrivateKey = P-256_NAMED_CURVE_EXPLICIT +-----BEGIN PRIVATE KEY----- +MIIBeQIBADCCAQMGByqGSM49AgEwgfcCAQEwLAYHKoZIzj0BAQIhAP////8AAAAB +AAAAAAAAAAAAAAAA////////////////MFsEIP////8AAAABAAAAAAAAAAAAAAAA +///////////////8BCBaxjXYqjqT57PrvVV2mIa8ZR0GsMxTsPY7zjw+J9JgSwMV +AMSdNgiG5wSTamZ44ROdJreBn36QBEEEaxfR8uEsQkf4vOblY6RA8ncDfYEt6zOg +9KE5RdiYwpZP40Li/hp/m47n60p8D54WK84zV2sxXs7LtkBoN79R9QIhAP////8A +AAAA//////////+85vqtpxeehPO5ysL8YyVRAgEBBG0wawIBAQQgiUTxtr5vLVjj +0BOXUa/4r82DJ30QoupYS/wlilW4gWehRANCAATM0n3q2UaDyaQ7OxzJM3B6prhW +3ev1gTwRBduzqqlwd54AUSgI+pjttW8zrWNitO8H1sf59MPWOESKxNtZ1+Nl +-----END PRIVATE KEY----- + +PrivateKey = EC_EXPLICIT +-----BEGIN PRIVATE KEY----- +MIIBeQIBADCCAQMGByqGSM49AgEwgfcCAQEwLAYHKoZIzj0BAQIhAP////8AAAAB +AAAAAAAAAAAAAAAA////////////////MFsEIP////8AAAABAAAAAAAAAAAAAAAA +///////////////8BCBaxjXYqjqT57PrvVV2mIa8ZR0GsMxTsPY7zjw+J9JgSwMV +AMSdNgiG5wSTamZ44ROdJreBn36QBEEE5JcIvn36opqjEm/k59Al40rBAxWM2TPG +l0L13Je51zHpfXQ9Z2o7IQicMXP4wSfJ0qCgg2bgydqoxlYrlLGuVQIhAP////8A +AAAA//////////+85vqtpxeehPO5ysL8YyVRAgEBBG0wawIBAQQgec92jwduadCk +OjoNRI+YT5Be5TkzZXzYCyTLkMOikDmhRANCAATtECEhQbLEaiUj/Wu0qjcr81lL +46dx5zYgArz/iaSNJ3W80oO+F7v04jlQ7wxQzg96R0bwKiMeq5CcW9ZFt6xg +-----END PRIVATE KEY----- + +PrivateKey = B-163 +-----BEGIN PRIVATE KEY----- +MGMCAQAwEAYHKoZIzj0CAQYFK4EEAA8ETDBKAgEBBBUDnQW0mLiHVha/jqFznX/K +DnVlDgChLgMsAAQB1qZ00fPIct+QN8skv1XIHtBNp3EGLytJV0tsAUTYtGhtrzRj +e3GzYyg= +-----END PRIVATE KEY----- + +PrivateKey = secp256k1 +-----BEGIN PRIVATE KEY----- +MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQgsLpFV9joHc0bisyV53XL +mrG6/Gu6ZaHoXtKP/VFX44ehRANCAARLYWGgp5nP4N8guypLSbYGCVN6ZPCnWW4x +srYkcpdbxr4neRT3zC62keCKgPbJf5SIHkJ2Tcaw6hVSrBOUFtix +-----END PRIVATE KEY----- + +Title = FIPS tests + +# Test that a nist curve with SHA3 is allowed in fips mode +# The sign will get a mismatch error since the output signature changes on each run +Sign-Message = ECDSA-SHA3-512:P-256 +Input = "Hello World" +Result = KEYOP_MISMATCH diff --git a/EvpTestRecipes/3.5/evppkey_rsa_sigalg.txt b/EvpTestRecipes/3.5/evppkey_rsa_sigalg.txt new file mode 100644 index 00000000..81e2d990 --- /dev/null +++ b/EvpTestRecipes/3.5/evppkey_rsa_sigalg.txt @@ -0,0 +1,157 @@ +# +# Copyright 2001-2025 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +# Tests start with one of these keywords +# Cipher Decrypt Derive Digest Encoding KDF MAC PBE +# PrivPubKeyPair Sign Verify VerifyRecover +# and continue until a blank line. Lines starting with a pound sign are ignored. +# The keyword Availablein must appear before the test name if needed. + +# Private keys used for PKEY operations. + +# RSA 2048 bit key. + +PrivateKey = RSA-2048 +-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDNAIHqeyrh6gbV +n3xz2f+5SglhXC5Lp8Y2zvCN01M+wxhVJbAVx2m5mnfWclv5w1Mqm25fZifV+4UW +B2jT3anL01l0URcX3D0wnS/EfuQfl+Mq23+d2GShxHZ6Zm7NcbwarPXnUX9LOFlP +6psF5C1a2pkSAIAT5FMWpNm7jtCGuI0odYusr5ItRqhotIXSOcm66w4rZFknEPQr +LR6gpLSALAvsqzKPimiwBzvbVG/uqYCdKEmRKzkMFTK8finHZY+BdfrkbzQzL/h7 +yrPkBkm5hXeGnaDqcYNT8HInVIhpE2SHYNEivmduD8SD3SD/wxvalqMZZsmqLnWt +A95H4cRPAgMBAAECggEAYCl6x5kbFnoG1rJHWLjL4gi+ubLZ7Jc4vYD5Ci41AF3X +ziktnim6iFvTFv7x8gkTvArJDWsICLJBTYIQREHYYkozzgIzyPeApIs3Wv8C12cS +IopwJITbP56+zM+77hcJ26GCgA2Unp5CFuC/81WDiPi9kNo3Oh2CdD7D+90UJ/0W +glplejFpEuhpU2URfKL4RckJQF/KxV+JX8FdIDhsJu54yemQdQKaF4psHkzwwgDo +qc+yfp0Vb4bmwq3CKxqEoc1cpbJ5CHXXlAfISzUjlcuBzD/tW7BDtp7eDAcgRVAC +XO6MX0QBcLYSC7SOD3R7zY9SIRCFDfBDxCjf0YcFMQKBgQD2+WG0fLwDXTrt68fe +hQqVa2Xs25z2B2QGPxWqSFU8WNly/mZ1BW413f3De/O58vYi7icTNyVoScm+8hdv +6PfD+LuRujdN1TuvPeyBTSvewQwf3IjN0Wh28mse36PwlBl+301C/x+ylxEDuJjK +hZxCcocIaoQqtBC7ac8tNa9r4wKBgQDUfnJKf/QQSLJwwlJKQQGHi3MVm7c9PbwY +eyIOY1s1NPluJDoYTZP4YLa/u2txwe2aHh9FhYMCPDAelqaSwaCLU9DsnKkQEA2A +RR47fcagG6xK7O+N95iEa8I1oIy7os9MBoBMwRIZ6VYIxxTj8UMNSR+tu6MqV1Gg +T5d0WDTJpQKBgCHyRSu5uV39AoyRS/eZ8cp36JqV1Q08FtOE+EVfi9evnrPfo9WR +2YQt7yNfdjCo5IwIj/ZkLhAXlFNakz4el2+oUJ/HKLLaDEoaCNf883q6rh/zABrK +HcG7sF2d/7qhoJ9/se7zgjfZ68zHIrkzhDbd5xGREnmMJoCcGo3sQyBhAoGAH3UQ +qmLC2N5KPFMoJ4H0HgLQ6LQCrnhDLkScSBEBYaEUA/AtAYgKjcyTgVLXlyGkcRpg +esRHHr+WSBD5W+R6ReYEmeKfTJdzyDdzQE9gZjdyjC0DUbsDwybIu3OnIef6VEDq +IXK7oUZfzDDcsNn4mTDoFaoff5cpqFfgDgM43VkCgYBNHw11b+d+AQmaZS9QqIt7 +aF3FvwCYHV0jdv0Mb+Kc1bY4c0R5MFpzrTwVmdOerjuuA1+9b+0Hwo3nBZM4eaBu +SOamA2hu2OJWCl9q8fLCT69KqWDjghhvFe7c6aJJGucwaA3Uz3eLcPqoaCarMiNH +fMkTd7GabVourqIZdgvu1Q== +-----END PRIVATE KEY----- + +# Corresponding public key + +PublicKey = RSA-2048-PUBLIC +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzQCB6nsq4eoG1Z98c9n/ +uUoJYVwuS6fGNs7wjdNTPsMYVSWwFcdpuZp31nJb+cNTKptuX2Yn1fuFFgdo092p +y9NZdFEXF9w9MJ0vxH7kH5fjKtt/ndhkocR2emZuzXG8Gqz151F/SzhZT+qbBeQt +WtqZEgCAE+RTFqTZu47QhriNKHWLrK+SLUaoaLSF0jnJuusOK2RZJxD0Ky0eoKS0 +gCwL7Ksyj4posAc721Rv7qmAnShJkSs5DBUyvH4px2WPgXX65G80My/4e8qz5AZJ +uYV3hp2g6nGDU/ByJ1SIaRNkh2DRIr5nbg/Eg90g/8Mb2pajGWbJqi51rQPeR+HE +TwIDAQAB +-----END PUBLIC KEY----- + +PrivPubKeyPair = RSA-2048:RSA-2048-PUBLIC + +Title = RSA tests with EVP_PKEY_sign, EVP_PKEY_verify + +# Demonstrate the possibility to use the RSA (not RSA-SHA1) signature +# implementation with EVP_PKEY_sign_init_ex2() the same way as with +# EVP_PKEY_sign_init_ex(). +Sign = RSA:RSA-2048 +Ctrl = digest:SHA1 +Input = "0123456789ABCDEF1234" +Output = c09d402423cbf233d26cae21f954547bc43fe80fd41360a0336cfdbe9aedad05bef6fd2eaee6cd60089a52482d4809a238149520df3bdde4cb9e23d9307b05c0a6f327052325a29adf2cc95b66523be7024e2a585c3d4db15dfbe146efe0ecdc0402e33fe5d40324ee96c5c3edd374a15cdc0f5d84aa243c0f07e188c6518fbfceae158a9943be398e31097da81b62074f626eff738be6160741d5a26957a482b3251fd85d8df78b98148459de10aa93305dbb4a5230aa1da291a9b0e481918f99b7638d72bb687f97661d304ae145d64a474437a4ef39d7b8059332ddeb07e92bf6e0e3acaf8afedc93795e4511737ec1e7aab6d5bc9466afc950c1c17b48ad + +Sign = RSA-SHA1:RSA-2048 +Input = "0123456789ABCDEF1234" +Output = c09d402423cbf233d26cae21f954547bc43fe80fd41360a0336cfdbe9aedad05bef6fd2eaee6cd60089a52482d4809a238149520df3bdde4cb9e23d9307b05c0a6f327052325a29adf2cc95b66523be7024e2a585c3d4db15dfbe146efe0ecdc0402e33fe5d40324ee96c5c3edd374a15cdc0f5d84aa243c0f07e188c6518fbfceae158a9943be398e31097da81b62074f626eff738be6160741d5a26957a482b3251fd85d8df78b98148459de10aa93305dbb4a5230aa1da291a9b0e481918f99b7638d72bb687f97661d304ae145d64a474437a4ef39d7b8059332ddeb07e92bf6e0e3acaf8afedc93795e4511737ec1e7aab6d5bc9466afc950c1c17b48ad + +# Digest too long +Sign = RSA-SHA1:RSA-2048 +Input = "0123456789ABCDEF12345" +Output = 00 +Result = KEYOP_ERROR + +# Digest too short +Sign = RSA-SHA1:RSA-2048 +Input = "0123456789ABCDEF123" +Output = 00 +Result = KEYOP_ERROR + +# Truncated digest [copy from evppkey_rsa_common.txt] +Sign = RSA-SHA512-224:RSA-2048 +Input = "0123456789ABCDEF123456789ABC" +Output = 5f720e9488139bb21e1c2f027fd5ce5993e6d31c5a8faaee833487b3a944d66891178868ace8070cad3ee2ffbe54aa4885a15fd1a7cc5166970fe1fd8c0423e72bd3e3b56fc4a53ed80aaaeca42497f0ec3c62113edc05cd006608f5eef7ce3ad4cba1069f68731dd28a524a1f93fcdc5547112d48d45586dd943ba0d443be9635720d8a61697c54c96627f0d85c5fbeaa3b4af86a65cf2fc3800dd5de34c046985f25d0efc0bb6edccc1d08b3a4fb9c8faffe181c7e68b31e374ad1440a4a664eec9ca0dc53a9d2f5bc7d9940d866f64201bcbc63612754df45727ea24b531d7de83d1bb707444859fa35521320c33bf6f4dbeb6fb56e653adbf7af15843f17 + +Verify = RSA-SHA512-224:RSA-2048 +Input = "0123456789ABCDEF123456789ABC" +Output = 5f720e9488139bb21e1c2f027fd5ce5993e6d31c5a8faaee833487b3a944d66891178868ace8070cad3ee2ffbe54aa4885a15fd1a7cc5166970fe1fd8c0423e72bd3e3b56fc4a53ed80aaaeca42497f0ec3c62113edc05cd006608f5eef7ce3ad4cba1069f68731dd28a524a1f93fcdc5547112d48d45586dd943ba0d443be9635720d8a61697c54c96627f0d85c5fbeaa3b4af86a65cf2fc3800dd5de34c046985f25d0efc0bb6edccc1d08b3a4fb9c8faffe181c7e68b31e374ad1440a4a664eec9ca0dc53a9d2f5bc7d9940d866f64201bcbc63612754df45727ea24b531d7de83d1bb707444859fa35521320c33bf6f4dbeb6fb56e653adbf7af15843f17 + + +Title = RSA with EVP_PKEY_sign_message, EVP_PKEY_verify_message + +Sign-Message = RSA-SHA1:RSA-2048 +Input = "Hello World" +Output = 3da3ca2bdd1b23a231b0e3c49d95d5959f9398c27a1e534c7e6baf1d2682304d3b6b229385b1edf483f5ef6f9b35bf10c519a302bb2f79c564e1a59ba71aa2fa36df96c942c43e8d9bd4702b5f61c12a078ae2b34d0de221fc8f9f936b79a67c89d11ba5da8c63a1370d0e824c6b661123e9b58b143ff533cf362cbdad70e65b419a6d45723bf22db3c76bb8f5337c5c5c93cb6f38b30d0c835b54c23405ca4217dd0b755f3712ebad285d9e0c02655f6ce5ce6fed78f3c81843de325f628055eef57f280dee0c3170050137ee599b9ab7f2b5d3c5f831777ea05a5eb097c70bad1a7214dadae12d7960bb9425390c7d25a79985e1e3c28ad422ff93c808f4b5 + +Sign-Message = RSA-SHA256:RSA-2048 +Input = "Hello World" +Output = ba8c24b86f18633767ed1778ef12d283a508d0bef32dd50b4a67cbd6b75df0f4ef6e69bfafbc809b01b93ab34aad9a33908644efca6eca04db1afda1016d1c1603183d2263597cf85ce5b7acd6a4872cbcc401b90b221d85aa0a2d0e1f159fc0843e0a55c47dc108c3f207d000e954605fabbb8c938050f280e29653aa1438109d02e53dfbdcb8cb9b46d372dd39ba7317a3f4c0020dba1ddd247b3d58addb1df7208785a62a8e3e4372c1fa6d24a17cd6413f7f5c046ba40a881c21875fde848b3b56fea7264430eca15b27c5c3b72fedcbcc124f8d939ffc11e6d3172c7eb491d378902093fcc3bf3a2835a1fcfabf457c13abf7b37f08595ed72332e27034 + +# As there dont seem to be test vectors for these - they were just generated +# to verify that all digests are supported. +# +# The following can easily be verified manually with this or similar +# command, provided that the RSA-2048 private key is stored in key.pem, +# and that {hashname} is replaced with the actual hash name: +# +# echo -n 'Hello World' | openssl dgst -hex -sign key.pem -{hashname} +# +# That command uses the EVP_DigestSign API. + +Title = Test RSA with different digests + +Sign-Message = RSA-SHA224:RSA-2048 +Input = "Hello World" +Output = 4bae2cf892733233985102eb7117303e49994a8a97b3de64597c33f15a689502ba4dcea20f0ada460b262bd0c92db23dd090453f95debbfd7a835b51d1923ede76f4f66ba04d9ba0715b333a747c8d469283af653f286a307a3c46cd91f51ca2d597f9d3951fc068ff3ed45ba6b3540801159c7c890a252183de9e4aeb0512eb9ae681ac1d436c9efef9f265dcdf64ce67dce73d8a88bcb0008211bc6cd5493822818bfc208b8737ae38874184f834301de26e537694cfdc0abaccc2702820ee58cbba243aac685681329705999f4d77e596615293eb642ec450f149caabfab55092fc0315ec4157d322813ba9790c0f46c6805b8e1c0f21b6211c3529e6d7cc + +Sign-Message = RSA-SHA384:RSA-2048 +Input = "Hello World" +Output = 041348caa7ffaa7dce1ac67567c408967a1736dd44ff73076570a63c4c7128ff09f716918b81fdfaa160368bc8b85c23466f8c0d4172da880386b75065f541c0fb6c9355a1731532ebab9cf5026cafe03a790bc1698586fbdff5f6e8f1a7148b07f1f895a99d0f041b8b36d8ffdd5e77ba36e5177610e0825ba78594f95826dabdc95f682da04edf0d133c55e78fa386dea9dbc1cf748e768e9116976476e75a84b5510d869beac9a1a9ffc579a28629154b24ee9df8d51fee479f4dca5646a2032c27206ad30f4937fc096c41362562bee74562132a4f471bb4b4c76e774be0e9eca9412809665ab13951d3699b3a7ccb6714a0f070345f6f3e037bd0f8ae52 + +Sign-Message = RSA-SHA512:RSA-2048 +Input = "Hello World" +Output = 32e1f87fcd81a9d5a9f988087cdb3931fe0b12197d501b9c958cc1614a236e71a00ee7c96f7d5b3ae5ae3f11e40df5d06b0a818ee2a573aa1459f7f14dc22ca0b0b0ad2d47f4ab9e479baa084973b69f74f691ee700af102aceaf788e513f0e942a862bc6884ef1efb993b11d2ebd95139c61c37f8eac3edd94a4d8a358842f17da6d2971b8141a70097a1de569751eb4533e27880206fb8f8e1ac995688ca6facc85ed116becea9d3c4d0e96b2cb4b422b21c81328a335441d897c7deebf0f605ef086cfc5d81d1ab30ac04f674993511b142ea7ad43a8d3b7b1d2d26ce4a93413b690afdb1718408379fbd002a3c569bf11f0c10ce7cb46e257ce6b62ef62b + +Sign-Message = RSA-SHA512-224:RSA-2048 +Input = "Hello World" +Output = 8f20f0f2389408cfb7f4b47c299ca610c34a2ad20664378530ecf977c3243ce5f01c71296d2101dc962853a27f64a228eea92fee05780be31cdd7fe648d39f136de1dd857609d0d54d0de52c5cdf09d95986d808d1c92dcb3e8e96848af788c959927196316fcc56b884d34711a2a947b7e806caf7a2b05314f0c726b5e083baa0b341ac6515529bf6b3a7098a635c865e8d4b05af68fb3e893feb12ac7c4d667e1233f2e39449c285d4ad2a809e687f68ef66daf710e7d21e97833372c251bc0b45bc79c8bfe4087f16662875c2fc91a02d11078556a2b3232617406fbd947b9d95c193742ac4bb1858934ed7288cd0327c678b5295c682a4d2ba91d8fafae7 + +Sign-Message = RSA-SHA512-256:RSA-2048 +Input = "Hello World" +Output = 00904130234e4e1a51060f7747ab26ca766c64cff1df97e4d0f432169046da422305ddea16b96e0d8fcc5ab651ac247d1b65283f2f27e7e97538e9f6b77f9558c9885d5ddacaf4d6ca600ad61693766498fa815361cd1debe2d71a5af77da71f8bd72d2f5cf741aa177a2dc44107f5887d95b217c67dbc5a4874f9aa8de1fc8a5645815c561edcb348db6458018096a99a98f5d2e677f068c9093618e28f532a97e8d6161aec002d5273884ce8b46f077d37b1e158de682a927126952bdbb6b6dfdf47d7e34a7d9c9b1395315586a11ceadfb72c021b28e28b8397bc9086418a45cb8c1ad46ef47f1c2bedb14b50e50b58bd607992e1d19b895119c6a62471b4 + +Sign-Message = RSA-SHA3-224:RSA-2048 +Input = "Hello World" +Output = 5b6f6834356ba08ef649d822592d7a3d889995283e3752760b0728ed99aa05af901298159485a690f8dab21c850946ef2376bedcc87f403288039e1eb18dfdf4ac1075753528c94b5a8b11f74513ef64eddc215f7df97d977e788fd93db4063529fd87f583c1c98d39cd79178330bae7980d9a846acdf3bdd77a864f85b77941b375c076ff86def44b8da19b5de6131bb8894c870d4deeb62361bd429faad97530abab33795912d63f2fb886b25f1a1d9583fae3b7cf6dd6a5addd1b28320ab88a4dac2d938fb50b6c9115c7a0a4edd6b7b3453e435605839703f0b0c6e58f7bb73ef0fb38cab4f2d9dc1fd8b8b77b36ae945dea7563eaa33608781ce5ac181b + +Sign-Message = RSA-SHA3-256:RSA-2048 +Input = "Hello World" +Output = c531d0db6635b7c58c7118641565796c3d61323e303246cfc39e4e697727fede52b029407f82aa07e25c4833d18ec6ef6b585f3f078ca1494ae80a696fec701e1c2386196100cc5879fb8ea77f07b7019185258e1ad632c28cc672a61296787bb16a0e4f259d6eac1960f7eaaee1f7ab7eea3cf2d9e11435859630f0c71c48c8655b1252e072f18831731b2bc8e788a722c77db57583c7456e9b7fd5273e6781e214616620084dfefffe506910a39087912c3a8586fce65d8a0b1e5803ffe59b53537119653d708a55ef17d2721b9c8c183fe6750991b0e77b79d8d208ad750b2bc3426fbeeebf9b090bfc19f6534e44bf6d7d2f2e1dc2594b38ceda420553c9 + +Sign-Message = RSA-SHA3-384:RSA-2048 +Input = "Hello World" +Output = 78bc11342fd44b4c047a365cc6ef78476bf28547da4eafec09f6bdf68a5593e993716662801b313515d80ddd232dfcc414cf896349a0237976dd89a97a9c88a92cd86992996d9c2747bf4e5dff5acb2fc67aa51ceb27ed1b95edd952d8eab3055cdc576a860593308c426f7ea73e01bd05fb20a4fcb64b10945e1684da67a8367826535344ad25057b4840e138909668c2423669b51f2fec631fd7e919f6e8b82ee293878894cac6a58b21f2168ba6335197e39e587fd60076a369f0b8e779c045c507654fbb98f5ffc998f720ab48bdbfe6d397aa63c7209b45068e24b65371180ff6d775851b2aaceac393082920fffb9e8b6999c682875bd0eff231dfaadf + +Sign-Message = RSA-SHA3-512:RSA-2048 +Input = "Hello World" +Output = 4681312b0e27e4e5f2dd3165ea5bdc98210d4883709a842239cef72099d71855fc322c3d2f74a7e7357647de153c22e4c4f9a0e4f1ce9b7f993242df5ee778ca949e6e184551e87e0aac8440ae990ef76a14f6056a16181390ad3a150bfdbb985cfe4cca3255b5eb0871116654d59fc89f69adb46c307b927c51a5f34069a2f43c854fde8e2df0ded10f8e257d1d800aa44bf31981f93c062128cc551ad7f5f7ba68e9d7c917c8fc51bcda3ce9192680c1e5308bd5c571ac0a5ae7347a897e8698ea94059562cd3035e3ed5fcf6c4ca8c20f58a079dfcdb175242a5726237d1b92378ec7dc4f2db09a0fbd62d1ab6d1a3d0be7afd34ed9c3ecd1bc5a3d2c448c diff --git a/ScosslCommon/inc/scossl_ecc.h b/ScosslCommon/inc/scossl_ecc.h index 21826351..0e2512ee 100644 --- a/ScosslCommon/inc/scossl_ecc.h +++ b/ScosslCommon/inc/scossl_ecc.h @@ -8,6 +8,14 @@ extern "C" { #endif +// If r and s are both 0, the DER encoding would be 8 bytes +// (0x30 0x06 0x02 0x01 0x00 0x02 0x01 0x00) +// integers must contain at least 1 octet of content in DER +#define SCOSSL_ECDSA_MIN_DER_SIGNATURE_LEN (8) +// Largest supported curve is P521 => 66 * 2 + 4 (int headers) + 3 (seq header) +#define SCOSSL_ECDSA_MAX_DER_SIGNATURE_LEN (139) +// Smallest supported curve is P192 => 24 * 2 byte SymCrypt signatures +#define SCOSSL_ECDSA_MIN_SYMCRYPT_SIGNATURE_LEN (48) // Largest supported curve is P521 => 66 * 2 byte SymCrypt signatures #define SCOSSL_ECDSA_MAX_SYMCRYPT_SIGNATURE_LEN (132) @@ -31,9 +39,9 @@ SIZE_T scossl_ecdsa_size(_In_ PCSYMCRYPT_ECURVE curve); SCOSSL_STATUS scossl_ecdsa_sign(_In_ PSYMCRYPT_ECKEY key, _In_ PCSYMCRYPT_ECURVE curve, _In_reads_bytes_(cbHashValue) PCBYTE pbHashValue, SIZE_T cbHashValue, _Out_writes_bytes_opt_(*pcbSignature) PBYTE pbSignature, _Out_ unsigned int* pcbSignature); -SCOSSL_STATUS scossl_ecdsa_verify(_In_ PSYMCRYPT_ECKEY key, _In_ PCSYMCRYPT_ECURVE curve, - _In_reads_bytes_(cbHashValue) PCBYTE pbHashValue, SIZE_T cbHashValue, - _In_reads_bytes_(pcbSignature) PCBYTE pbSignature, SIZE_T pcbSignature); +int scossl_ecdsa_verify(_In_ PSYMCRYPT_ECKEY key, _In_ PCSYMCRYPT_ECURVE curve, + _In_reads_bytes_(cbHashValue) PCBYTE pbHashValue, SIZE_T cbHashValue, + _In_reads_bytes_(pcbSignature) PCBYTE pbSignature, SIZE_T pcbSignature); #ifdef __cplusplus } diff --git a/ScosslCommon/src/scossl_ecc.c b/ScosslCommon/src/scossl_ecc.c index 6e6b66c4..447d9a90 100644 --- a/ScosslCommon/src/scossl_ecc.c +++ b/ScosslCommon/src/scossl_ecc.c @@ -14,15 +14,6 @@ extern "C" { #define NID_secp192r1 (NID_X9_62_prime192v1) #define NID_secp256r1 (NID_X9_62_prime256v1) -// If r and s are both 0, the DER encoding would be 8 bytes -// (0x30 0x06 0x02 0x01 0x00 0x02 0x01 0x00) -// integers must contain at least 1 octet of content in DER -#define SCOSSL_ECDSA_MIN_DER_SIGNATURE_LEN (8) -// Largest supported curve is P521 => 66 * 2 + 4 (int headers) + 3 (seq header) -#define SCOSSL_ECDSA_MAX_DER_SIGNATURE_LEN (139) -// Smallest supported curve is P192 => 24 * 2 byte SymCrypt signatures -#define SCOSSL_ECDSA_MIN_SYMCRYPT_SIGNATURE_LEN (48) - static BOOL scossl_ecc_initialized = FALSE; static PSYMCRYPT_ECURVE _hidden_curve_P192 = NULL; static PSYMCRYPT_ECURVE _hidden_curve_P224 = NULL; @@ -422,13 +413,13 @@ SCOSSL_STATUS scossl_ecc_init_static() ((_hidden_curve_P256 = SymCryptEcurveAllocate(SymCryptEcurveParamsNistP256, 0)) == NULL) || ((_hidden_curve_P384 = SymCryptEcurveAllocate(SymCryptEcurveParamsNistP384, 0)) == NULL) || ((_hidden_curve_P521 = SymCryptEcurveAllocate(SymCryptEcurveParamsNistP521, 0)) == NULL) || - ((_hidden_curve_X25519 = SymCryptEcurveAllocate(SymCryptEcurveParamsCurve25519, 0)) == NULL) || + ((_hidden_curve_X25519 = SymCryptEcurveAllocate(SymCryptEcurveParamsCurve25519, 0)) == NULL) || ((_hidden_curve_brainpoolP256r1 = SymCryptEcurveAllocate(SymCryptEcurveParamsBrainpoolP256r1, 0)) == NULL) || ((_hidden_curve_brainpoolP384r1 = SymCryptEcurveAllocate(SymCryptEcurveParamsBrainpoolP384r1, 0)) == NULL) || ((_hidden_curve_brainpoolP512r1 = SymCryptEcurveAllocate(SymCryptEcurveParamsBrainpoolP512r1, 0)) == NULL) || ((_hidden_curve_brainpoolP256t1 = SymCryptEcurveAllocate(SymCryptEcurveParamsBrainpoolP256t1, 0)) == NULL) || - ((_hidden_curve_brainpoolP384t1 = SymCryptEcurveAllocate(SymCryptEcurveParamsBrainpoolP384t1, 0)) == NULL) || - ((_hidden_curve_brainpoolP512t1 = SymCryptEcurveAllocate(SymCryptEcurveParamsBrainpoolP512t1, 0)) == NULL)) + ((_hidden_curve_brainpoolP384t1 = SymCryptEcurveAllocate(SymCryptEcurveParamsBrainpoolP384t1, 0)) == NULL) || + ((_hidden_curve_brainpoolP512t1 = SymCryptEcurveAllocate(SymCryptEcurveParamsBrainpoolP512t1, 0)) == NULL)) { return SCOSSL_FAILURE; } @@ -1068,10 +1059,14 @@ SCOSSL_STATUS scossl_ecdsa_sign(PSYMCRYPT_ECKEY key, PCSYMCRYPT_ECURVE curve, return SCOSSL_SUCCESS; } +// Return +// 1 (SCOSSL_SUCCESS) for valid signature +// 0 (SCOSSL_FAILURE) for invalid signature +// -1 for error _Use_decl_annotations_ -SCOSSL_STATUS scossl_ecdsa_verify(PSYMCRYPT_ECKEY key, PCSYMCRYPT_ECURVE curve, - PCBYTE pbHashValue, SIZE_T cbHashValue, - PCBYTE pbSignature, SIZE_T pcbSignature) +int scossl_ecdsa_verify(PSYMCRYPT_ECKEY key, PCSYMCRYPT_ECURVE curve, + PCBYTE pbHashValue, SIZE_T cbHashValue, + PCBYTE pbSignature, SIZE_T pcbSignature) { SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR; BYTE buf[SCOSSL_ECDSA_MAX_SYMCRYPT_SIGNATURE_LEN] = {0}; @@ -1082,14 +1077,14 @@ SCOSSL_STATUS scossl_ecdsa_verify(PSYMCRYPT_ECKEY key, PCSYMCRYPT_ECURVE curve, { SCOSSL_LOG_SYMCRYPT_ERROR(SCOSSL_ERR_F_ECDSA_VERIFY, "SymCryptEckeyExtendKeyUsage failed", scError); - return SCOSSL_FAILURE; + return -1; } - if (!scossl_ecdsa_remove_der(pbSignature, pcbSignature, &buf[0], cbSymCryptSig)) + if (scossl_ecdsa_remove_der(pbSignature, pcbSignature, &buf[0], cbSymCryptSig) != SCOSSL_SUCCESS) { SCOSSL_LOG_ERROR(SCOSSL_ERR_F_ECDSA_VERIFY, ERR_R_OPERATION_FAIL, "scossl_ecdsa_remove_der failed"); - return SCOSSL_FAILURE; + return -1; } scError = SymCryptEcDsaVerify( diff --git a/ScosslCommon/src/scossl_rsa.c b/ScosslCommon/src/scossl_rsa.c index 66a9916a..1bc7b91d 100644 --- a/ScosslCommon/src/scossl_rsa.c +++ b/ScosslCommon/src/scossl_rsa.c @@ -266,11 +266,9 @@ SCOSSL_STATUS scossl_rsapss_sign(PSYMCRYPT_RSAKEY key, int mdnid, int cbSalt, case RSA_PSS_SALTLEN_MAX: cbSalt = cbSaltMax; break; -#ifdef RSA_PSS_SALTLEN_AUTO_DIGEST_MAX // Added in 3.1, smaller of digest length or maximized salt length case RSA_PSS_SALTLEN_AUTO_DIGEST_MAX: cbSalt = cbSaltMax < (int)cbHashValue ? cbSaltMax : (int)cbHashValue; -#endif } if (cbSalt < 0 || cbSalt > cbSaltMax) @@ -370,10 +368,8 @@ SCOSSL_STATUS scossl_rsapss_verify(PSYMCRYPT_RSAKEY key, int mdnid, int cbSalt, cbSalt = cbSaltMax; break; case RSA_PSS_SALTLEN_AUTO: -#ifdef RSA_PSS_SALTLEN_AUTO_DIGEST_MAX // Added in 3.1; auto salt len for verify case RSA_PSS_SALTLEN_AUTO_DIGEST_MAX: -#endif scFlags = SYMCRYPT_FLAG_RSA_PSS_VERIFY_WITH_MINIMUM_SALT; cbSalt = 0; } diff --git a/SymCryptEngine/src/e_scossl_ecc.c b/SymCryptEngine/src/e_scossl_ecc.c index 57e92cb6..79ce3c23 100644 --- a/SymCryptEngine/src/e_scossl_ecc.c +++ b/SymCryptEngine/src/e_scossl_ecc.c @@ -606,7 +606,11 @@ ECDSA_SIG* e_scossl_eckey_sign_sig(_In_reads_bytes_(dgstlen) const unsigned char return returnSignature; } -SCOSSL_STATUS e_scossl_eckey_verify(int type, _In_reads_bytes_(dgst_len) const unsigned char* dgst, int dgst_len, +// Return +// 1 (SCOSSL_SUCCESS) for valid signature +// 0 (SCOSSL_FAILURE) for invalid signature +// -1 for error +int e_scossl_eckey_verify(int type, _In_reads_bytes_(dgst_len) const unsigned char* dgst, int dgst_len, _In_reads_bytes_(sig_len) const unsigned char* sigbuf, int sig_len, _In_ EC_KEY* eckey) { const EC_KEY_METHOD* ossl_eckey_method = NULL; diff --git a/SymCryptEngine/src/e_scossl_ecc.h b/SymCryptEngine/src/e_scossl_ecc.h index 2a75bdf4..ad830bb0 100644 --- a/SymCryptEngine/src/e_scossl_ecc.h +++ b/SymCryptEngine/src/e_scossl_ecc.h @@ -64,7 +64,7 @@ ECDSA_SIG* e_scossl_eckey_sign_sig(_In_reads_bytes_(dgstlen) const unsigned char // Verifies that the signature in sigbuf of size sig_len is a valid ECDSA signature of the hash value dgst // of size dgst_len using the public key eckey. The parameter type is ignored. // Returns 1 for a valid signature, 0 for an invalid signature, and -1 on error. -SCOSSL_STATUS e_scossl_eckey_verify(int type, _In_reads_bytes_(dgst_len) const unsigned char* dgst, int dgst_len, +int e_scossl_eckey_verify(int type, _In_reads_bytes_(dgst_len) const unsigned char* dgst, int dgst_len, _In_reads_bytes_(sig_len) const unsigned char* sigbuf, int sig_len, _In_ EC_KEY* eckey); // Verifies that the signature in sig is a valid ECDSA signature of the hash value dgst of size dgst_len diff --git a/SymCryptProvider/CMakeLists.txt b/SymCryptProvider/CMakeLists.txt index 18f7bb2c..7e8471cf 100644 --- a/SymCryptProvider/CMakeLists.txt +++ b/SymCryptProvider/CMakeLists.txt @@ -51,7 +51,9 @@ set(SCOSSL_SOURCES ./src/mac/p_scossl_hmac.c ./src/mac/p_scossl_kmac.c ./src/signature/p_scossl_ecdsa_signature.c + ./src/signature/p_scossl_ecdsa_sigalg_signature.c ./src/signature/p_scossl_rsa_signature.c + ./src/signature/p_scossl_rsa_sigalg_signature.c ./src/skeymgmt/p_scossl_aes_skeymgmt.c ./src/skeymgmt/p_scossl_generic_skeymgmt.c ./src/p_scossl_bio.c diff --git a/SymCryptProvider/src/p_scossl_base.c b/SymCryptProvider/src/p_scossl_base.c index e092410a..ca5efef9 100644 --- a/SymCryptProvider/src/p_scossl_base.c +++ b/SymCryptProvider/src/p_scossl_base.c @@ -465,12 +465,52 @@ static const OSSL_ALGORITHM p_scossl_keyexch[] = { ALG_TABLE_END}; // Signature -extern const OSSL_DISPATCH p_scossl_ecdsa_signature_functions[]; extern const OSSL_DISPATCH p_scossl_rsa_signature_functions[]; +extern const OSSL_DISPATCH p_scossl_rsa_sha1_signature_functions[]; +extern const OSSL_DISPATCH p_scossl_rsa_sha224_signature_functions[]; +extern const OSSL_DISPATCH p_scossl_rsa_sha256_signature_functions[]; +extern const OSSL_DISPATCH p_scossl_rsa_sha384_signature_functions[]; +extern const OSSL_DISPATCH p_scossl_rsa_sha512_signature_functions[]; +extern const OSSL_DISPATCH p_scossl_rsa_sha512_224_signature_functions[]; +extern const OSSL_DISPATCH p_scossl_rsa_sha512_256_signature_functions[]; +extern const OSSL_DISPATCH p_scossl_rsa_sha3_224_signature_functions[]; +extern const OSSL_DISPATCH p_scossl_rsa_sha3_256_signature_functions[]; +extern const OSSL_DISPATCH p_scossl_rsa_sha3_384_signature_functions[]; +extern const OSSL_DISPATCH p_scossl_rsa_sha3_512_signature_functions[]; +extern const OSSL_DISPATCH p_scossl_ecdsa_signature_functions[]; +extern const OSSL_DISPATCH p_scossl_ecdsa_sha1_signature_functions[]; +extern const OSSL_DISPATCH p_scossl_ecdsa_sha224_signature_functions[]; +extern const OSSL_DISPATCH p_scossl_ecdsa_sha256_signature_functions[]; +extern const OSSL_DISPATCH p_scossl_ecdsa_sha384_signature_functions[]; +extern const OSSL_DISPATCH p_scossl_ecdsa_sha512_signature_functions[]; +extern const OSSL_DISPATCH p_scossl_ecdsa_sha3_224_signature_functions[]; +extern const OSSL_DISPATCH p_scossl_ecdsa_sha3_256_signature_functions[]; +extern const OSSL_DISPATCH p_scossl_ecdsa_sha3_384_signature_functions[]; +extern const OSSL_DISPATCH p_scossl_ecdsa_sha3_512_signature_functions[]; static const OSSL_ALGORITHM p_scossl_signature[] = { - ALG(SCOSSL_ALG_NAME_ECDSA, p_scossl_ecdsa_signature_functions), ALG(SCOSSL_ALG_NAME_RSA, p_scossl_rsa_signature_functions), + ALG(SCOSSL_ALG_NAME_RSA_SHA1, p_scossl_rsa_sha1_signature_functions), + ALG(SCOSSL_ALG_NAME_RSA_SHA256, p_scossl_rsa_sha256_signature_functions), + ALG(SCOSSL_ALG_NAME_RSA_SHA384, p_scossl_rsa_sha384_signature_functions), + ALG(SCOSSL_ALG_NAME_RSA_SHA512, p_scossl_rsa_sha512_signature_functions), + ALG(SCOSSL_ALG_NAME_RSA_SHA224, p_scossl_rsa_sha224_signature_functions), + ALG(SCOSSL_ALG_NAME_RSA_SHA512_224, p_scossl_rsa_sha512_224_signature_functions), + ALG(SCOSSL_ALG_NAME_RSA_SHA512_256, p_scossl_rsa_sha512_256_signature_functions), + ALG(SCOSSL_ALG_NAME_RSA_SHA3_224, p_scossl_rsa_sha3_224_signature_functions), + ALG(SCOSSL_ALG_NAME_RSA_SHA3_256, p_scossl_rsa_sha3_256_signature_functions), + ALG(SCOSSL_ALG_NAME_RSA_SHA3_384, p_scossl_rsa_sha3_384_signature_functions), + ALG(SCOSSL_ALG_NAME_RSA_SHA3_512, p_scossl_rsa_sha3_512_signature_functions), + ALG(SCOSSL_ALG_NAME_ECDSA, p_scossl_ecdsa_signature_functions), + ALG(SCOSSL_ALG_NAME_ECDSA_SHA1, p_scossl_ecdsa_sha1_signature_functions), + ALG(SCOSSL_ALG_NAME_ECDSA_SHA224, p_scossl_ecdsa_sha224_signature_functions), + ALG(SCOSSL_ALG_NAME_ECDSA_SHA256, p_scossl_ecdsa_sha256_signature_functions), + ALG(SCOSSL_ALG_NAME_ECDSA_SHA384, p_scossl_ecdsa_sha384_signature_functions), + ALG(SCOSSL_ALG_NAME_ECDSA_SHA512, p_scossl_ecdsa_sha512_signature_functions), + ALG(SCOSSL_ALG_NAME_ECDSA_SHA3_224, p_scossl_ecdsa_sha3_224_signature_functions), + ALG(SCOSSL_ALG_NAME_ECDSA_SHA3_256, p_scossl_ecdsa_sha3_256_signature_functions), + ALG(SCOSSL_ALG_NAME_ECDSA_SHA3_384, p_scossl_ecdsa_sha3_384_signature_functions), + ALG(SCOSSL_ALG_NAME_ECDSA_SHA3_512, p_scossl_ecdsa_sha3_512_signature_functions), ALG_TABLE_END}; // Asymmetric Cipher diff --git a/SymCryptProvider/src/p_scossl_names.h b/SymCryptProvider/src/p_scossl_names.h index 33ce0e94..43aa51fc 100644 --- a/SymCryptProvider/src/p_scossl_names.h +++ b/SymCryptProvider/src/p_scossl_names.h @@ -85,6 +85,30 @@ extern "C" { #define SCOSSL_ALG_NAME_RSA SN_rsa":"LN_rsaEncryption":1.2.840.113549.1.1.1" #define SCOSSL_ALG_NAME_ECDSA "ECDSA" +// Composite RSA signature algorithms (sigalgs) +#define SCOSSL_ALG_NAME_RSA_SHA1 "RSA-SHA1:RSA-SHA-1:sha1WithRSAEncryption:1.2.840.113549.1.1.5" +#define SCOSSL_ALG_NAME_RSA_SHA256 "RSA-SHA2-256:RSA-SHA256:sha256WithRSAEncryption:1.2.840.113549.1.1.11" +#define SCOSSL_ALG_NAME_RSA_SHA384 "RSA-SHA2-384:RSA-SHA384:sha384WithRSAEncryption:1.2.840.113549.1.1.12" +#define SCOSSL_ALG_NAME_RSA_SHA512 "RSA-SHA2-512:RSA-SHA512:sha512WithRSAEncryption:1.2.840.113549.1.1.13" +#define SCOSSL_ALG_NAME_RSA_SHA224 "RSA-SHA2-224:RSA-SHA224:sha224WithRSAEncryption:1.2.840.113549.1.1.14" +#define SCOSSL_ALG_NAME_RSA_SHA512_224 "RSA-SHA2-512/224:RSA-SHA512-224:sha512-224WithRSAEncryption:1.2.840.113549.1.1.15" +#define SCOSSL_ALG_NAME_RSA_SHA512_256 "RSA-SHA2-512/256:RSA-SHA512-256:sha512-256WithRSAEncryption:1.2.840.113549.1.1.16" +#define SCOSSL_ALG_NAME_RSA_SHA3_224 "RSA-SHA3-224:id-rsassa-pkcs1-v1_5-with-sha3-224:2.16.840.1.101.3.4.3.13" +#define SCOSSL_ALG_NAME_RSA_SHA3_256 "RSA-SHA3-256:id-rsassa-pkcs1-v1_5-with-sha3-256:2.16.840.1.101.3.4.3.14" +#define SCOSSL_ALG_NAME_RSA_SHA3_384 "RSA-SHA3-384:id-rsassa-pkcs1-v1_5-with-sha3-384:2.16.840.1.101.3.4.3.15" +#define SCOSSL_ALG_NAME_RSA_SHA3_512 "RSA-SHA3-512:id-rsassa-pkcs1-v1_5-with-sha3-512:2.16.840.1.101.3.4.3.16" + +// Composite ECDSA signature algorithms (sigalgs) +#define SCOSSL_ALG_NAME_ECDSA_SHA1 "ECDSA-SHA1:ECDSA-SHA-1:ecdsa-with-SHA1:1.2.840.10045.4.1" +#define SCOSSL_ALG_NAME_ECDSA_SHA224 "ECDSA-SHA2-224:ECDSA-SHA224:ecdsa-with-SHA224:1.2.840.10045.4.3.1" +#define SCOSSL_ALG_NAME_ECDSA_SHA256 "ECDSA-SHA2-256:ECDSA-SHA256:ecdsa-with-SHA256:1.2.840.10045.4.3.2" +#define SCOSSL_ALG_NAME_ECDSA_SHA384 "ECDSA-SHA2-384:ECDSA-SHA384:ecdsa-with-SHA384:1.2.840.10045.4.3.3" +#define SCOSSL_ALG_NAME_ECDSA_SHA512 "ECDSA-SHA2-512:ECDSA-SHA512:ecdsa-with-SHA512:1.2.840.10045.4.3.4" +#define SCOSSL_ALG_NAME_ECDSA_SHA3_224 "ECDSA-SHA3-224:ecdsa_with_SHA3-224:id-ecdsa-with-sha3-224:2.16.840.1.101.3.4.3.9" +#define SCOSSL_ALG_NAME_ECDSA_SHA3_256 "ECDSA-SHA3-256:ecdsa_with_SHA3-256:id-ecdsa-with-sha3-256:2.16.840.1.101.3.4.3.10" +#define SCOSSL_ALG_NAME_ECDSA_SHA3_384 "ECDSA-SHA3-384:ecdsa_with_SHA3-384:id-ecdsa-with-sha3-384:2.16.840.1.101.3.4.3.11" +#define SCOSSL_ALG_NAME_ECDSA_SHA3_512 "ECDSA-SHA3-512:ecdsa_with_SHA3-512:id-ecdsa-with-sha3-512:2.16.840.1.101.3.4.3.12" + // Key encapsulation #define SCOSSL_ALG_NAME_MLKEM512 SCOSSL_LN_MLKEM512":MLKEM512:"SCOSSL_SN_MLKEM512":"SCOSSL_OID_MLKEM512 #define SCOSSL_ALG_NAME_MLKEM768 SCOSSL_LN_MLKEM768":MLKEM768:"SCOSSL_SN_MLKEM768":"SCOSSL_OID_MLKEM768 diff --git a/SymCryptProvider/src/signature/p_scossl_ecdsa_sigalg_signature.c b/SymCryptProvider/src/signature/p_scossl_ecdsa_sigalg_signature.c new file mode 100644 index 00000000..0954990c --- /dev/null +++ b/SymCryptProvider/src/signature/p_scossl_ecdsa_sigalg_signature.c @@ -0,0 +1,391 @@ +// +// Copyright (c) Microsoft Corporation. Licensed under the MIT license. +// + +#include +#include +#include +#include + +#include "p_scossl_ecdsa_signature.h" + +#ifdef __cplusplus +extern "C" { +#endif + +static const OSSL_PARAM p_scossl_ecdsa_sigalg_ctx_settable_param_types[] = { + OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_SIGNATURE, NULL, 0), + OSSL_PARAM_END}; + +static SCOSSL_STATUS p_scossl_ecdsa_sigalg_signverify_init(_Inout_ SCOSSL_ECDSA_CTX *ctx, _In_ SCOSSL_ECC_KEY_CTX *keyCtx, + _In_ const OSSL_PARAM params[], _In_ const char *mdname, + int operation) +{ + if (!p_scossl_ecdsa_signverify_init(ctx, keyCtx, params, operation)) + { + return SCOSSL_FAILURE; + } + + EVP_MD_free(ctx->md); + + ctx->md = EVP_MD_fetch(ctx->libctx, mdname, NULL); + if (ctx->md == NULL) + { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST); + return SCOSSL_FAILURE; + } + + ctx->mdSize = EVP_MD_get_size(ctx->md); + ctx->allowMdUpdates = FALSE; + ctx->isSigalg = TRUE; + + return SCOSSL_SUCCESS; +} + +static SCOSSL_STATUS p_scossl_ecdsa_sigalg_message_signverify_init(_Inout_ SCOSSL_ECDSA_CTX *ctx, _In_ SCOSSL_ECC_KEY_CTX *keyCtx, + _In_ const OSSL_PARAM params[], _In_ const char *mdname, + int operation) +{ + if (!p_scossl_ecdsa_sigalg_signverify_init(ctx, keyCtx, params, mdname, operation)) + { + return SCOSSL_FAILURE; + } + + if (ctx->mdctx == NULL && + ((ctx->mdctx = EVP_MD_CTX_new()) == NULL)) + { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + return SCOSSL_FAILURE; + } + + if (!EVP_DigestInit_ex2(ctx->mdctx, ctx->md, params)) + { + EVP_MD_CTX_free(ctx->mdctx); + ctx->mdctx = NULL; + return SCOSSL_FAILURE; + } + + return SCOSSL_SUCCESS; +} + +static SCOSSL_STATUS p_scossl_ecdsa_sigalg_signverify_message_update(_In_ SCOSSL_ECDSA_CTX *ctx, + _In_reads_bytes_(inlen) const unsigned char *in, + size_t inlen) +{ + if (ctx == NULL || ctx->mdctx == NULL) + { + ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); + return SCOSSL_FAILURE; + } + + if (!ctx->allowUpdate) + { + ERR_raise(ERR_LIB_PROV, PROV_R_UPDATE_CALL_OUT_OF_ORDER); + return SCOSSL_FAILURE; + } + + ctx->allowOneshot = FALSE; + + return EVP_DigestUpdate(ctx->mdctx, in, inlen); +} + +static SCOSSL_STATUS p_scossl_ecdsa_sigalg_sign_message_final(_In_ SCOSSL_ECDSA_CTX *ctx, + _Out_writes_bytes_opt_(*siglen) unsigned char *sig, + _Out_ size_t *siglen, size_t sigsize) +{ + BYTE digest[EVP_MAX_MD_SIZE]; + unsigned int cbDigest = 0; + + if (ctx == NULL) + { + ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); + return SCOSSL_FAILURE; + } + + if (ctx->mdctx == NULL) + { + ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST); + return 0; + } + + if (!ctx->allowFinal) + { + ERR_raise(ERR_LIB_PROV, PROV_R_FINAL_CALL_OUT_OF_ORDER); + return SCOSSL_FAILURE; + } + + // If sig is NULL, this is a size fetch, and the digest does not need to be computed + if (sig != NULL) + { + if (!EVP_DigestFinal_ex(ctx->mdctx, digest, &cbDigest)) + { + return SCOSSL_FAILURE; + } + + ctx->allowUpdate = FALSE; + ctx->allowOneshot = FALSE; + ctx->allowFinal = FALSE; + } + + return p_scossl_ecdsa_sign_internal(ctx, sig, siglen, sigsize, digest, cbDigest); +} + +// Return +// 1 (SCOSSL_SUCCESS) for valid signature +// 0 (SCOSSL_FAILURE) for invalid signature +// -1 for error +static int p_scossl_ecdsa_sigalg_verify_message_final(_In_ SCOSSL_ECDSA_CTX *ctx) +{ + BYTE digest[EVP_MAX_MD_SIZE]; + unsigned int cbDigest = 0; + + if (ctx == NULL) + { + ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (ctx->mdctx == NULL) + { + ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST); + return 0; + } + + if (!ctx->allowFinal) + { + ERR_raise(ERR_LIB_PROV, PROV_R_FINAL_CALL_OUT_OF_ORDER); + return 0; + } + + if (ctx->pbSignature == NULL) + { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SIGNATURE_SIZE); + return 0; + } + + if (!EVP_DigestFinal_ex(ctx->mdctx, digest, &cbDigest)) + { + return 0; + } + + ctx->allowUpdate = FALSE; + ctx->allowFinal = FALSE; + ctx->allowOneshot = FALSE; + + return p_scossl_ecdsa_verify_internal(ctx, ctx->pbSignature, ctx->cbSignature, digest, cbDigest); +} + +static SCOSSL_STATUS p_scossl_ecdsa_sigalg_sign(_In_ SCOSSL_ECDSA_CTX *ctx, + _Out_writes_bytes_opt_(*siglen) unsigned char *sig, _Out_ size_t *siglen, size_t sigsize, + _In_reads_bytes_(tbslen) const unsigned char *tbs, size_t tbslen) +{ + if (ctx == NULL) + { + ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); + return SCOSSL_FAILURE; + } + + if (!ctx->allowOneshot) + { + ERR_raise(ERR_LIB_PROV, PROV_R_ONESHOT_CALL_OUT_OF_ORDER); + return SCOSSL_FAILURE; + } + + if (ctx->operation == EVP_PKEY_OP_SIGNMSG) + { + // If sig is NULL, the caller is only looking for the sig length. + // Do not update the input in this case. + if (sig == NULL) + { + return p_scossl_ecdsa_sigalg_sign_message_final(ctx, sig, siglen, sigsize); + } + + if (p_scossl_ecdsa_sigalg_signverify_message_update(ctx, tbs, tbslen) <= 0) + { + return SCOSSL_FAILURE; + } + + return p_scossl_ecdsa_sigalg_sign_message_final(ctx, sig, siglen, sigsize); + } + + return p_scossl_ecdsa_sign_internal(ctx, sig, siglen, sigsize, tbs, tbslen); +} + +// Return +// 1 (SCOSSL_SUCCESS) for valid signature +// 0 (SCOSSL_FAILURE) for invalid signature +// -1 for error +static int p_scossl_ecdsa_sigalg_verify(_In_ SCOSSL_ECDSA_CTX *ctx, + _In_reads_bytes_(siglen) const unsigned char *sig, size_t siglen, + _In_reads_bytes_(tbslen) const unsigned char *tbs, size_t tbslen) +{ + if (ctx == NULL) + { + ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (!ctx->allowOneshot) + { + ERR_raise(ERR_LIB_PROV, PROV_R_ONESHOT_CALL_OUT_OF_ORDER); + return 0; + } + + if (ctx->operation == EVP_PKEY_OP_VERIFYMSG) + { + OPENSSL_free(ctx->pbSignature); + ctx->pbSignature = NULL; + ctx->cbSignature = 0; + + if (siglen == 0 || + siglen > SCOSSL_ECDSA_MAX_DER_SIGNATURE_LEN) + { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SIGNATURE_SIZE); + return 0; + } + + if ((ctx->pbSignature = OPENSSL_memdup(sig, siglen)) == NULL) + { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + return 0; + } + ctx->cbSignature = siglen; + + if (p_scossl_ecdsa_sigalg_signverify_message_update(ctx, tbs, tbslen) <= 0) + { + return 0; + } + + return p_scossl_ecdsa_sigalg_verify_message_final(ctx); + } + + return p_scossl_ecdsa_verify_internal(ctx, sig, siglen, tbs, tbslen); +} + +static const OSSL_PARAM *p_scossl_ecdsa_sigalg_settable_ctx_params(_In_ SCOSSL_ECDSA_CTX *ctx, + ossl_unused void *provctx) +{ + if (ctx != NULL && ctx->operation == EVP_PKEY_OP_VERIFYMSG) + { + return p_scossl_ecdsa_sigalg_ctx_settable_param_types; + } + + return NULL; +} + +static SCOSSL_STATUS p_scossl_ecdsa_sigalg_set_ctx_params(_Inout_ SCOSSL_ECDSA_CTX *ctx, + _In_ const OSSL_PARAM params[]) +{ + const OSSL_PARAM *p; + + if (ctx == NULL) + { + ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); + return SCOSSL_FAILURE; + } + + if (ctx->operation == EVP_PKEY_OP_VERIFYMSG) + { + if ((p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_SIGNATURE)) != NULL) + { + PCBYTE pcbSignature = NULL; + SIZE_T cbSignature = 0; + + OPENSSL_free(ctx->pbSignature); + ctx->pbSignature = NULL; + ctx->cbSignature = 0; + + if (!OSSL_PARAM_get_octet_string_ptr(p, (const void **)&pcbSignature, &cbSignature)) + { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); + return SCOSSL_FAILURE; + } + + if (cbSignature == 0 || + cbSignature > SCOSSL_ECDSA_MAX_DER_SIGNATURE_LEN) + { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SIGNATURE_SIZE); + return SCOSSL_FAILURE; + } + + if ((ctx->pbSignature = OPENSSL_memdup(pcbSignature, cbSignature)) == NULL) + { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + return SCOSSL_FAILURE; + } + ctx->cbSignature = cbSignature; + } + } + + return SCOSSL_SUCCESS; +} + +static const char **p_scossl_ecdsa_sigalg_query_key_types(void) +{ + static const char *keyTypes[] = { "EC", NULL }; + return keyTypes; +} + +#define IMPL_SCOSSL_ECDSA_SIGALG(md, MD) \ + static SCOSSL_STATUS p_scossl_ecdsa_##md##_sign_init(_Inout_ SCOSSL_ECDSA_CTX *ctx, \ + _In_ SCOSSL_ECC_KEY_CTX *keyCtx, \ + _In_ const OSSL_PARAM params[]) \ + { \ + return p_scossl_ecdsa_sigalg_signverify_init(ctx, keyCtx, params, MD, EVP_PKEY_OP_SIGN); \ + } \ + \ + static SCOSSL_STATUS p_scossl_ecdsa_##md##_verify_init(_Inout_ SCOSSL_ECDSA_CTX *ctx, \ + _In_ SCOSSL_ECC_KEY_CTX *keyCtx, \ + _In_ const OSSL_PARAM params[]) \ + { \ + return p_scossl_ecdsa_sigalg_signverify_init(ctx, keyCtx, params, MD, EVP_PKEY_OP_VERIFY); \ + } \ + \ + static SCOSSL_STATUS p_scossl_ecdsa_##md##_sign_message_init(_Inout_ SCOSSL_ECDSA_CTX *ctx, \ + _In_ SCOSSL_ECC_KEY_CTX *keyCtx, \ + _In_ const OSSL_PARAM params[]) \ + { \ + return p_scossl_ecdsa_sigalg_message_signverify_init(ctx, keyCtx, params, MD, EVP_PKEY_OP_SIGNMSG); \ + } \ + \ + static SCOSSL_STATUS p_scossl_ecdsa_##md##_verify_message_init(_Inout_ SCOSSL_ECDSA_CTX *ctx, \ + _In_ SCOSSL_ECC_KEY_CTX *keyCtx, \ + _In_ const OSSL_PARAM params[]) \ + { \ + return p_scossl_ecdsa_sigalg_message_signverify_init(ctx, keyCtx, params, MD, EVP_PKEY_OP_VERIFYMSG); \ + } \ + \ + const OSSL_DISPATCH p_scossl_ecdsa_##md##_signature_functions[] = { \ + {OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))p_scossl_ecdsa_newctx}, \ + {OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))p_scossl_ecdsa_dupctx}, \ + {OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))p_scossl_ecdsa_freectx}, \ + {OSSL_FUNC_SIGNATURE_SIGN_INIT, (void (*)(void))p_scossl_ecdsa_##md##_sign_init}, \ + {OSSL_FUNC_SIGNATURE_SIGN, (void (*)(void))p_scossl_ecdsa_sigalg_sign}, \ + {OSSL_FUNC_SIGNATURE_SIGN_MESSAGE_INIT, (void (*)(void))p_scossl_ecdsa_##md##_sign_message_init}, \ + {OSSL_FUNC_SIGNATURE_SIGN_MESSAGE_UPDATE, (void (*)(void))p_scossl_ecdsa_sigalg_signverify_message_update}, \ + {OSSL_FUNC_SIGNATURE_SIGN_MESSAGE_FINAL, (void (*)(void))p_scossl_ecdsa_sigalg_sign_message_final}, \ + {OSSL_FUNC_SIGNATURE_VERIFY_INIT, (void (*)(void))p_scossl_ecdsa_##md##_verify_init}, \ + {OSSL_FUNC_SIGNATURE_VERIFY, (void (*)(void))p_scossl_ecdsa_sigalg_verify}, \ + {OSSL_FUNC_SIGNATURE_VERIFY_MESSAGE_INIT, (void (*)(void))p_scossl_ecdsa_##md##_verify_message_init}, \ + {OSSL_FUNC_SIGNATURE_VERIFY_MESSAGE_UPDATE, (void (*)(void))p_scossl_ecdsa_sigalg_signverify_message_update}, \ + {OSSL_FUNC_SIGNATURE_VERIFY_MESSAGE_FINAL, (void (*)(void))p_scossl_ecdsa_sigalg_verify_message_final},\ + {OSSL_FUNC_SIGNATURE_QUERY_KEY_TYPES, (void (*)(void))p_scossl_ecdsa_sigalg_query_key_types}, \ + {OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, (void (*)(void))p_scossl_ecdsa_get_ctx_params}, \ + {OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, (void (*)(void))p_scossl_ecdsa_gettable_ctx_params}, \ + {OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, (void (*)(void))p_scossl_ecdsa_sigalg_set_ctx_params}, \ + {OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, (void (*)(void))p_scossl_ecdsa_sigalg_settable_ctx_params}, \ + {0, NULL}}; + +IMPL_SCOSSL_ECDSA_SIGALG(sha1, OSSL_DIGEST_NAME_SHA1) +IMPL_SCOSSL_ECDSA_SIGALG(sha224, OSSL_DIGEST_NAME_SHA2_224) +IMPL_SCOSSL_ECDSA_SIGALG(sha256, OSSL_DIGEST_NAME_SHA2_256) +IMPL_SCOSSL_ECDSA_SIGALG(sha384, OSSL_DIGEST_NAME_SHA2_384) +IMPL_SCOSSL_ECDSA_SIGALG(sha512, OSSL_DIGEST_NAME_SHA2_512) +IMPL_SCOSSL_ECDSA_SIGALG(sha3_224, OSSL_DIGEST_NAME_SHA3_224) +IMPL_SCOSSL_ECDSA_SIGALG(sha3_256, OSSL_DIGEST_NAME_SHA3_256) +IMPL_SCOSSL_ECDSA_SIGALG(sha3_384, OSSL_DIGEST_NAME_SHA3_384) +IMPL_SCOSSL_ECDSA_SIGALG(sha3_512, OSSL_DIGEST_NAME_SHA3_512) + +#ifdef __cplusplus +} +#endif diff --git a/SymCryptProvider/src/signature/p_scossl_ecdsa_signature.c b/SymCryptProvider/src/signature/p_scossl_ecdsa_signature.c index f455901a..b84bedbc 100644 --- a/SymCryptProvider/src/signature/p_scossl_ecdsa_signature.c +++ b/SymCryptProvider/src/signature/p_scossl_ecdsa_signature.c @@ -2,31 +2,15 @@ // Copyright (c) Microsoft Corporation. Licensed under the MIT license. // -#include "scossl_ecc.h" -#include "p_scossl_ecc.h" -#include "p_scossl_base.h" +#include "p_scossl_ecdsa_signature.h" +#include #include #ifdef __cplusplus extern "C" { #endif -typedef struct -{ - SCOSSL_ECC_KEY_CTX *keyCtx; - int operation; - - // Needed for fetching md - OSSL_LIB_CTX *libctx; - char* propq; - - EVP_MD_CTX *mdctx; - EVP_MD *md; - SIZE_T mdSize; - BOOL allowMdUpdates; -} SCOSSL_ECDSA_CTX; - static const OSSL_PARAM p_scossl_ecdsa_ctx_gettable_param_types[] = { OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0), OSSL_PARAM_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE, NULL), @@ -45,7 +29,8 @@ static const OSSL_PARAM p_scossl_ecdsa_ctx_settable_param_types_no_digest[] = { static SCOSSL_STATUS p_scossl_ecdsa_set_ctx_params(_Inout_ SCOSSL_ECDSA_CTX *ctx, _In_ const OSSL_PARAM params[]); -static SCOSSL_ECDSA_CTX *p_scossl_ecdsa_newctx(_In_ SCOSSL_PROVCTX *provctx, _In_ const char *propq) +_Use_decl_annotations_ +SCOSSL_ECDSA_CTX *p_scossl_ecdsa_newctx(SCOSSL_PROVCTX *provctx, const char *propq) { SCOSSL_ECDSA_CTX *ctx = OPENSSL_zalloc(sizeof(SCOSSL_ECDSA_CTX)); if (ctx != NULL) @@ -64,7 +49,7 @@ static SCOSSL_ECDSA_CTX *p_scossl_ecdsa_newctx(_In_ SCOSSL_PROVCTX *provctx, _In return ctx; } -static void p_scossl_ecdsa_freectx(SCOSSL_ECDSA_CTX *ctx) +void p_scossl_ecdsa_freectx(SCOSSL_ECDSA_CTX *ctx) { if (ctx == NULL) return; @@ -72,36 +57,45 @@ static void p_scossl_ecdsa_freectx(SCOSSL_ECDSA_CTX *ctx) EVP_MD_CTX_free(ctx->mdctx); EVP_MD_free(ctx->md); OPENSSL_free(ctx->propq); + OPENSSL_free(ctx->pbSignature); OPENSSL_free(ctx); } -static SCOSSL_ECDSA_CTX *p_scossl_ecdsa_dupctx(_In_ SCOSSL_ECDSA_CTX *ctx) +_Use_decl_annotations_ +SCOSSL_ECDSA_CTX *p_scossl_ecdsa_dupctx(SCOSSL_ECDSA_CTX *ctx) { SCOSSL_ECDSA_CTX *copyCtx = OPENSSL_zalloc(sizeof(SCOSSL_ECDSA_CTX)); if (copyCtx != NULL) { if ((ctx->propq != NULL && ((copyCtx->propq = OPENSSL_strdup(ctx->propq)) == NULL)) || (ctx->mdctx != NULL && ((copyCtx->mdctx = EVP_MD_CTX_dup((const EVP_MD_CTX *)ctx->mdctx)) == NULL)) || - (ctx->md != NULL && !EVP_MD_up_ref(ctx->md))) + (ctx->md != NULL && !EVP_MD_up_ref(ctx->md)) || + (ctx->pbSignature != NULL && ((copyCtx->pbSignature = OPENSSL_memdup(ctx->pbSignature, ctx->cbSignature)) == NULL))) { p_scossl_ecdsa_freectx(copyCtx); ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); - copyCtx = NULL; + return NULL; } copyCtx->keyCtx = ctx->keyCtx; copyCtx->operation = ctx->operation; copyCtx->libctx = ctx->libctx; copyCtx->md = ctx->md; - ctx->mdSize = ctx->mdSize; + copyCtx->mdSize = ctx->mdSize; copyCtx->allowMdUpdates = ctx->allowMdUpdates; + copyCtx->isSigalg = ctx->isSigalg; + copyCtx->allowUpdate = ctx->allowUpdate; + copyCtx->allowFinal = ctx->allowFinal; + copyCtx->allowOneshot = ctx->allowOneshot; + copyCtx->cbSignature = ctx->cbSignature; } return copyCtx; } -static SCOSSL_STATUS p_scossl_ecdsa_signverify_init(_Inout_ SCOSSL_ECDSA_CTX *ctx, _In_ SCOSSL_ECC_KEY_CTX *keyCtx, - _In_ const OSSL_PARAM params[], int operation) +_Use_decl_annotations_ +SCOSSL_STATUS p_scossl_ecdsa_signverify_init(SCOSSL_ECDSA_CTX *ctx, SCOSSL_ECC_KEY_CTX *keyCtx, + const OSSL_PARAM params[], int operation) { if (ctx == NULL || (keyCtx == NULL && ctx->keyCtx == NULL)) @@ -111,6 +105,10 @@ static SCOSSL_STATUS p_scossl_ecdsa_signverify_init(_Inout_ SCOSSL_ECDSA_CTX *ct } ctx->operation = operation; + ctx->isSigalg = FALSE; + ctx->allowUpdate = TRUE; + ctx->allowFinal = TRUE; + ctx->allowOneshot = TRUE; if (keyCtx != NULL) { @@ -123,7 +121,7 @@ static SCOSSL_STATUS p_scossl_ecdsa_signverify_init(_Inout_ SCOSSL_ECDSA_CTX *ct ctx->keyCtx = keyCtx; #ifdef KEYSINUSE_ENABLED if (keysinuse_is_running() && - operation == EVP_PKEY_OP_SIGN) + (operation == EVP_PKEY_OP_SIGN || operation == EVP_PKEY_OP_SIGNMSG)) { p_scossl_ecc_init_keysinuse(keyCtx); } @@ -144,10 +142,10 @@ static SCOSSL_STATUS p_scossl_ecdsa_verify_init(_Inout_ SCOSSL_ECDSA_CTX *ctx, _ { return p_scossl_ecdsa_signverify_init(ctx, keyCtx, params, EVP_PKEY_OP_VERIFY); } - -static SCOSSL_STATUS p_scossl_ecdsa_sign(_In_ SCOSSL_ECDSA_CTX *ctx, - _Out_writes_bytes_(*siglen) unsigned char *sig, _Out_ size_t *siglen, size_t sigsize, - _In_reads_bytes_(tbslen) const unsigned char *tbs, size_t tbslen) +_Use_decl_annotations_ +SCOSSL_STATUS p_scossl_ecdsa_sign_internal(SCOSSL_ECDSA_CTX *ctx, + unsigned char *sig, size_t *siglen, size_t sigsize, + const unsigned char *tbs, size_t tbslen) { SIZE_T cbResult; @@ -157,12 +155,6 @@ static SCOSSL_STATUS p_scossl_ecdsa_sign(_In_ SCOSSL_ECDSA_CTX *ctx, return SCOSSL_FAILURE; } - if (ctx->operation != EVP_PKEY_OP_SIGN) - { - ERR_raise(ERR_LIB_PROV, ERR_R_OPERATION_FAIL); - return SCOSSL_FAILURE; - } - if (siglen == NULL) { ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); @@ -204,22 +196,17 @@ static SCOSSL_STATUS p_scossl_ecdsa_sign(_In_ SCOSSL_ECDSA_CTX *ctx, // 1 (SCOSSL_SUCCESS) for valid signature // 0 (SCOSSL_FAILURE) for invalid signature // -1 for error -static int p_scossl_ecdsa_verify(_In_ SCOSSL_ECDSA_CTX *ctx, - _In_reads_bytes_(siglen) const unsigned char *sig, size_t siglen, - _In_reads_bytes_(tbslen) const unsigned char *tbs, size_t tbslen) +_Use_decl_annotations_ +int p_scossl_ecdsa_verify_internal(SCOSSL_ECDSA_CTX *ctx, + const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen) { - if (ctx == NULL || ctx->keyCtx == NULL) + if (ctx->keyCtx == NULL) { ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET); return -1; } - if (ctx->operation != EVP_PKEY_OP_VERIFY) - { - ERR_raise(ERR_LIB_PROV, ERR_R_OPERATION_FAIL); - return -1; - } - return scossl_ecdsa_verify(ctx->keyCtx->key, ctx->keyCtx->curve, tbs, tbslen, sig, siglen); } @@ -282,7 +269,7 @@ static SCOSSL_STATUS p_scossl_ecdsa_digest_signverify_update(_In_ SCOSSL_ECDSA_C } static SCOSSL_STATUS p_scossl_ecdsa_digest_sign_final(_In_ SCOSSL_ECDSA_CTX *ctx, - _Out_writes_bytes_(*siglen) unsigned char *sig, _Out_ size_t *siglen, size_t sigsize) + _Out_writes_bytes_opt_(*siglen) unsigned char *sig, _Out_ size_t *siglen, size_t sigsize) { BYTE digest[EVP_MAX_MD_SIZE]; unsigned int cbDigest = 0; @@ -303,7 +290,7 @@ static SCOSSL_STATUS p_scossl_ecdsa_digest_sign_final(_In_ SCOSSL_ECDSA_CTX *ctx } } - return p_scossl_ecdsa_sign(ctx, sig, siglen, sigsize, digest, cbDigest); + return p_scossl_ecdsa_sign_internal(ctx, sig, siglen, sigsize, digest, cbDigest); } static int p_scossl_ecdsa_digest_verify_final(_In_ SCOSSL_ECDSA_CTX *ctx, @@ -312,8 +299,15 @@ static int p_scossl_ecdsa_digest_verify_final(_In_ SCOSSL_ECDSA_CTX *ctx, BYTE digest[EVP_MAX_MD_SIZE]; unsigned int cbDigest = 0; + if (ctx == NULL) + { + ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (ctx->mdctx == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST); return 0; } @@ -324,7 +318,49 @@ static int p_scossl_ecdsa_digest_verify_final(_In_ SCOSSL_ECDSA_CTX *ctx, return 0; } - return p_scossl_ecdsa_verify(ctx, sig, siglen, digest, cbDigest); + return p_scossl_ecdsa_verify_internal(ctx, sig, siglen, digest, cbDigest); +} + +static SCOSSL_STATUS p_scossl_ecdsa_sign(_In_ SCOSSL_ECDSA_CTX *ctx, + _Out_writes_bytes_opt_(*siglen) unsigned char *sig, _Out_ size_t *siglen, size_t sigsize, + _In_reads_bytes_(tbslen) const unsigned char *tbs, size_t tbslen) +{ + if (ctx == NULL) + { + ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET); + return SCOSSL_FAILURE; + } + + if (!ctx->allowOneshot) + { + ERR_raise(ERR_LIB_PROV, PROV_R_ONESHOT_CALL_OUT_OF_ORDER); + return SCOSSL_FAILURE; + } + + return p_scossl_ecdsa_sign_internal(ctx, sig, siglen, sigsize, tbs, tbslen); +} + +// Return +// 1 (SCOSSL_SUCCESS) for valid signature +// 0 (SCOSSL_FAILURE) for invalid signature +// -1 for error +static int p_scossl_ecdsa_verify(_In_ SCOSSL_ECDSA_CTX *ctx, + _In_reads_bytes_(siglen) const unsigned char *sig, size_t siglen, + _In_reads_bytes_(tbslen) const unsigned char *tbs, size_t tbslen) +{ + if (ctx == NULL) + { + ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (!ctx->allowOneshot) + { + ERR_raise(ERR_LIB_PROV, PROV_R_ONESHOT_CALL_OUT_OF_ORDER); + return 0; + } + + return p_scossl_ecdsa_verify_internal(ctx, sig, siglen, tbs, tbslen); } static const OSSL_PARAM *p_scossl_ecdsa_settable_ctx_params(_In_ SCOSSL_ECDSA_CTX *ctx, @@ -393,13 +429,15 @@ static SCOSSL_STATUS p_scossl_ecdsa_set_ctx_params(_Inout_ SCOSSL_ECDSA_CTX *ctx return SCOSSL_SUCCESS; } -static const OSSL_PARAM *p_scossl_ecdsa_gettable_ctx_params(ossl_unused void *ctx, - ossl_unused void *provctx) +_Use_decl_annotations_ +const OSSL_PARAM *p_scossl_ecdsa_gettable_ctx_params(ossl_unused void *ctx, + ossl_unused void *provctx) { return p_scossl_ecdsa_ctx_gettable_param_types; } -static SCOSSL_STATUS p_scossl_ecdsa_get_ctx_params(_In_ SCOSSL_ECDSA_CTX *ctx, _Inout_ OSSL_PARAM params[]) +_Use_decl_annotations_ +SCOSSL_STATUS p_scossl_ecdsa_get_ctx_params(SCOSSL_ECDSA_CTX *ctx, OSSL_PARAM params[]) { if (params == NULL) { diff --git a/SymCryptProvider/src/signature/p_scossl_ecdsa_signature.h b/SymCryptProvider/src/signature/p_scossl_ecdsa_signature.h new file mode 100644 index 00000000..e09b2e10 --- /dev/null +++ b/SymCryptProvider/src/signature/p_scossl_ecdsa_signature.h @@ -0,0 +1,62 @@ +// +// Copyright (c) Microsoft Corporation. Licensed under the MIT license. +// + +#pragma once + +#include +#include + +#include "scossl_ecc.h" +#include "p_scossl_ecc.h" +#include "p_scossl_base.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct +{ + SCOSSL_ECC_KEY_CTX *keyCtx; + int operation; + + // Needed for fetching md + OSSL_LIB_CTX *libctx; + char* propq; + + EVP_MD_CTX *mdctx; + EVP_MD *md; + SIZE_T mdSize; + BOOL allowMdUpdates; + + // Sigalg state tracking + BOOL isSigalg; + BOOL allowUpdate; + BOOL allowFinal; + BOOL allowOneshot; + + // Sigalg verify message support + PBYTE pbSignature; + SIZE_T cbSignature; +} SCOSSL_ECDSA_CTX; + +SCOSSL_ECDSA_CTX *p_scossl_ecdsa_newctx(_In_ SCOSSL_PROVCTX *provctx, _In_ const char *propq); +void p_scossl_ecdsa_freectx(_Inout_ SCOSSL_ECDSA_CTX *ctx); +SCOSSL_ECDSA_CTX *p_scossl_ecdsa_dupctx(_In_ SCOSSL_ECDSA_CTX *ctx); + +SCOSSL_STATUS p_scossl_ecdsa_signverify_init(_Inout_ SCOSSL_ECDSA_CTX *ctx, _In_ SCOSSL_ECC_KEY_CTX *keyCtx, + _In_ const OSSL_PARAM params[], int operation); + +SCOSSL_STATUS p_scossl_ecdsa_sign_internal(_In_ SCOSSL_ECDSA_CTX *ctx, + _Out_writes_bytes_opt_(*siglen) unsigned char *sig, _Out_ size_t *siglen, size_t sigsize, + _In_reads_bytes_(tbslen) const unsigned char *tbs, size_t tbslen); +int p_scossl_ecdsa_verify_internal(_In_ SCOSSL_ECDSA_CTX *ctx, + _In_reads_bytes_(siglen) const unsigned char *sig, size_t siglen, + _In_reads_bytes_(tbslen) const unsigned char *tbs, size_t tbslen); + +const OSSL_PARAM *p_scossl_ecdsa_gettable_ctx_params(ossl_unused void *ctx, ossl_unused void *provctx); +SCOSSL_STATUS p_scossl_ecdsa_get_ctx_params(_In_ SCOSSL_ECDSA_CTX *ctx, _Inout_ OSSL_PARAM params[]); + +#ifdef __cplusplus +} +#endif diff --git a/SymCryptProvider/src/signature/p_scossl_rsa_sigalg_signature.c b/SymCryptProvider/src/signature/p_scossl_rsa_sigalg_signature.c new file mode 100644 index 00000000..881c6748 --- /dev/null +++ b/SymCryptProvider/src/signature/p_scossl_rsa_sigalg_signature.c @@ -0,0 +1,383 @@ +// +// Copyright (c) Microsoft Corporation. Licensed under the MIT license. +// + +#include +#include +#include +#include + +#include "p_scossl_rsa_signature.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define SCOSSL_RSA_MAX_SIGNATURE_LEN (SYMCRYPT_RSAKEY_MAX_BITSIZE_MODULUS / 8) + +static const OSSL_PARAM p_scossl_rsa_sigalg_ctx_settable_param_types[] = { + OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_SIGNATURE, NULL, 0), + OSSL_PARAM_END}; + +static SCOSSL_STATUS p_scossl_rsa_sigalg_signverify_init(_Inout_ SCOSSL_RSA_SIGN_CTX *ctx, _In_ SCOSSL_PROV_RSA_KEY_CTX *keyCtx, + _In_ const OSSL_PARAM params[], int operation, + _In_ const char *mdname) +{ + EVP_MD *md = NULL; + const OSSL_ITEM *mdInfo = NULL; + + if (!p_scossl_rsa_signverify_init(ctx, keyCtx, params, operation)) + { + return SCOSSL_FAILURE; + } + + // Sigalgs are not supported for PSS keys + if (ctx->padding == RSA_PKCS1_PSS_PADDING) + { + ERR_raise(ERR_LIB_PROV, PROV_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return SCOSSL_FAILURE; + } + + mdInfo = p_scossl_rsa_get_supported_md(ctx->libctx, RSA_PKCS1_PADDING, mdname, NULL, &md); + if (mdInfo == NULL) + { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST); + return SCOSSL_FAILURE; + } + + EVP_MD_free(ctx->md); + ctx->md = md; + ctx->mdInfo = mdInfo; + ctx->padding = RSA_PKCS1_PADDING; + ctx->allowMdUpdates = FALSE; + ctx->isSigalg = TRUE; + + return SCOSSL_SUCCESS; +} + +static SCOSSL_STATUS p_scossl_rsa_sigalg_signverify_message_init(_Inout_ SCOSSL_RSA_SIGN_CTX *ctx, _In_ SCOSSL_PROV_RSA_KEY_CTX *keyCtx, + _In_ const OSSL_PARAM params[], int operation, + _In_ const char *mdname) +{ + if (!p_scossl_rsa_sigalg_signverify_init(ctx, keyCtx, params, operation, mdname)) + { + return SCOSSL_FAILURE; + } + + if (ctx->mdctx == NULL) + { + if ((ctx->mdctx = EVP_MD_CTX_new()) == NULL) + { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + return SCOSSL_FAILURE; + } + } + + if (!EVP_DigestInit_ex2(ctx->mdctx, ctx->md, params)) + { + EVP_MD_CTX_free(ctx->mdctx); + ctx->mdctx = NULL; + return SCOSSL_FAILURE; + } + + return SCOSSL_SUCCESS; +} + +static SCOSSL_STATUS p_scossl_rsa_sigalg_signverify_message_update(_In_ SCOSSL_RSA_SIGN_CTX *ctx, + _In_reads_bytes_(inlen) const unsigned char *in, + size_t inlen) +{ + if (ctx == NULL || ctx->mdctx == NULL) + { + ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); + return SCOSSL_FAILURE; + } + + if (!ctx->allowUpdate) + { + ERR_raise(ERR_LIB_PROV, PROV_R_UPDATE_CALL_OUT_OF_ORDER); + return SCOSSL_FAILURE; + } + + ctx->allowOneshot = FALSE; + + return EVP_DigestUpdate(ctx->mdctx, in, inlen); +} + +static SCOSSL_STATUS p_scossl_rsa_sigalg_sign_message_final(_In_ SCOSSL_RSA_SIGN_CTX *ctx, + _Out_writes_bytes_opt_(*siglen) unsigned char *sig, + _Out_ size_t *siglen, size_t sigsize) +{ + BYTE abDigest[EVP_MAX_MD_SIZE]; + unsigned int cbDigest = 0; + + if (ctx == NULL || ctx->mdctx == NULL) + { + ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); + return SCOSSL_FAILURE; + } + + if (!ctx->allowFinal) + { + ERR_raise(ERR_LIB_PROV, PROV_R_FINAL_CALL_OUT_OF_ORDER); + return SCOSSL_FAILURE; + } + + if (sig != NULL) + { + if (!EVP_DigestFinal_ex(ctx->mdctx, abDigest, &cbDigest)) + { + return SCOSSL_FAILURE; + } + + ctx->allowUpdate = FALSE; + ctx->allowFinal = FALSE; + ctx->allowOneshot = FALSE; + } + + return p_scossl_rsa_sign_internal(ctx, sig, siglen, sigsize, abDigest, cbDigest); +} + +static int p_scossl_rsa_sigalg_verify_message_final(_In_ SCOSSL_RSA_SIGN_CTX *ctx) +{ + BYTE abDigest[EVP_MAX_MD_SIZE]; + unsigned int cbDigest = 0; + + if (ctx == NULL || ctx->mdctx == NULL) + { + ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); + return SCOSSL_FAILURE; + } + + if (!ctx->allowFinal) + { + ERR_raise(ERR_LIB_PROV, PROV_R_FINAL_CALL_OUT_OF_ORDER); + return SCOSSL_FAILURE; + } + + if (ctx->pbSignature == NULL) + { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SIGNATURE_SIZE); + return SCOSSL_FAILURE; + } + + if (!EVP_DigestFinal_ex(ctx->mdctx, abDigest, &cbDigest)) + { + return SCOSSL_FAILURE; + } + + ctx->allowUpdate = FALSE; + ctx->allowFinal = FALSE; + ctx->allowOneshot = FALSE; + + return p_scossl_rsa_verify_internal(ctx, ctx->pbSignature, ctx->cbSignature, abDigest, cbDigest); +} + +static SCOSSL_STATUS p_scossl_rsa_sigalg_sign(_In_ SCOSSL_RSA_SIGN_CTX *ctx, + _Out_writes_bytes_opt_(*siglen) unsigned char *sig, _Out_ size_t *siglen, size_t sigsize, + _In_reads_bytes_(tbslen) const unsigned char *tbs, size_t tbslen) +{ + if (ctx == NULL) + { + ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); + return SCOSSL_FAILURE; + } + + if (!ctx->allowOneshot) + { + ERR_raise(ERR_LIB_PROV, PROV_R_ONESHOT_CALL_OUT_OF_ORDER); + return SCOSSL_FAILURE; + } + + if (ctx->operation == EVP_PKEY_OP_SIGNMSG) + { + if (sig == NULL) + { + return p_scossl_rsa_sigalg_sign_message_final(ctx, sig, siglen, sigsize); + } + + if (p_scossl_rsa_sigalg_signverify_message_update(ctx, tbs, tbslen) != SCOSSL_SUCCESS) + { + return SCOSSL_FAILURE; + } + + return p_scossl_rsa_sigalg_sign_message_final(ctx, sig, siglen, sigsize); + } + + return p_scossl_rsa_sign_internal(ctx, sig, siglen, sigsize, tbs, tbslen); +} + +static SCOSSL_STATUS p_scossl_rsa_sigalg_verify(_In_ SCOSSL_RSA_SIGN_CTX *ctx, + _In_reads_bytes_(siglen) const unsigned char *sig, size_t siglen, + _In_reads_bytes_(tbslen) const unsigned char *tbs, size_t tbslen) +{ + if (ctx == NULL) + { + ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); + return SCOSSL_FAILURE; + } + + if (!ctx->allowOneshot) + { + ERR_raise(ERR_LIB_PROV, PROV_R_ONESHOT_CALL_OUT_OF_ORDER); + return SCOSSL_FAILURE; + } + + if (ctx->operation == EVP_PKEY_OP_VERIFYMSG) + { + OPENSSL_free(ctx->pbSignature); + ctx->pbSignature = NULL; + ctx->cbSignature = 0; + + if (siglen == 0 || + siglen > SCOSSL_RSA_MAX_SIGNATURE_LEN) + { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SIGNATURE_SIZE); + return SCOSSL_FAILURE; + } + + if ((ctx->pbSignature = OPENSSL_memdup(sig, siglen)) == NULL) + { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + return SCOSSL_FAILURE; + } + ctx->cbSignature = siglen; + + if (p_scossl_rsa_sigalg_signverify_message_update(ctx, tbs, tbslen) != SCOSSL_SUCCESS) + { + return SCOSSL_FAILURE; + } + + return p_scossl_rsa_sigalg_verify_message_final(ctx); + } + + return p_scossl_rsa_verify_internal(ctx, sig, siglen, tbs, tbslen); +} + +static const OSSL_PARAM *p_scossl_rsa_sigalg_settable_ctx_params(_In_ SCOSSL_RSA_SIGN_CTX *ctx, ossl_unused void *provctx) +{ + if (ctx != NULL && ctx->operation == EVP_PKEY_OP_VERIFYMSG) + { + return p_scossl_rsa_sigalg_ctx_settable_param_types; + } + + return NULL; +} + +static SCOSSL_STATUS p_scossl_rsa_sigalg_set_ctx_params(_Inout_ SCOSSL_RSA_SIGN_CTX *ctx, _In_ const OSSL_PARAM params[]) +{ + const OSSL_PARAM *p; + + if (ctx == NULL) + { + ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); + return SCOSSL_FAILURE; + } + + if (ctx->operation == EVP_PKEY_OP_VERIFYMSG) + { + if ((p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_SIGNATURE)) != NULL) + { + PCBYTE pcbSignature = NULL; + SIZE_T cbSignature = 0; + + OPENSSL_free(ctx->pbSignature); + ctx->pbSignature = NULL; + ctx->cbSignature = 0; + + if (!OSSL_PARAM_get_octet_string_ptr(p, (const void **)&pcbSignature, &cbSignature)) + { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); + return SCOSSL_FAILURE; + } + + if (cbSignature == 0 || + cbSignature > SCOSSL_RSA_MAX_SIGNATURE_LEN) + { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SIGNATURE_SIZE); + return SCOSSL_FAILURE; + } + + if ((ctx->pbSignature = OPENSSL_memdup(pcbSignature, cbSignature)) == NULL) + { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + return SCOSSL_FAILURE; + } + ctx->cbSignature = cbSignature; + } + } + + return SCOSSL_SUCCESS; +} + +static const char **p_scossl_rsa_sigalg_query_key_types(void) +{ + static const char *keyTypes[] = { "RSA", NULL }; + return keyTypes; +} + +#define IMPLEMENT_SCOSSL_RSA_SIGALG(md, MD) \ + static SCOSSL_STATUS p_scossl_rsa_##md##_sign_init(_Inout_ SCOSSL_RSA_SIGN_CTX *ctx, \ + _In_ SCOSSL_PROV_RSA_KEY_CTX *keyCtx, \ + _In_ const OSSL_PARAM params[]) \ + { \ + return p_scossl_rsa_sigalg_signverify_init(ctx, keyCtx, params, EVP_PKEY_OP_SIGN, MD); \ + } \ + \ + static SCOSSL_STATUS p_scossl_rsa_##md##_verify_init(_Inout_ SCOSSL_RSA_SIGN_CTX *ctx, \ + _In_ SCOSSL_PROV_RSA_KEY_CTX *keyCtx, \ + _In_ const OSSL_PARAM params[]) \ + { \ + return p_scossl_rsa_sigalg_signverify_init(ctx, keyCtx, params, EVP_PKEY_OP_VERIFY, MD); \ + } \ + \ + static SCOSSL_STATUS p_scossl_rsa_##md##_sign_message_init(_Inout_ SCOSSL_RSA_SIGN_CTX *ctx, \ + _In_ SCOSSL_PROV_RSA_KEY_CTX *keyCtx, \ + _In_ const OSSL_PARAM params[]) \ + { \ + return p_scossl_rsa_sigalg_signverify_message_init(ctx, keyCtx, params, EVP_PKEY_OP_SIGNMSG, MD); \ + } \ + \ + static SCOSSL_STATUS p_scossl_rsa_##md##_verify_message_init(_Inout_ SCOSSL_RSA_SIGN_CTX *ctx, \ + _In_ SCOSSL_PROV_RSA_KEY_CTX *keyCtx, \ + _In_ const OSSL_PARAM params[]) \ + { \ + return p_scossl_rsa_sigalg_signverify_message_init(ctx, keyCtx, params, EVP_PKEY_OP_VERIFYMSG, MD); \ + } \ + \ + const OSSL_DISPATCH p_scossl_rsa_##md##_signature_functions[] = { \ + {OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))p_scossl_rsa_newctx}, \ + {OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))p_scossl_rsa_dupctx}, \ + {OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))p_scossl_rsa_freectx}, \ + {OSSL_FUNC_SIGNATURE_SIGN_INIT, (void (*)(void))p_scossl_rsa_##md##_sign_init}, \ + {OSSL_FUNC_SIGNATURE_SIGN, (void (*)(void))p_scossl_rsa_sigalg_sign}, \ + {OSSL_FUNC_SIGNATURE_SIGN_MESSAGE_INIT, (void (*)(void))p_scossl_rsa_##md##_sign_message_init}, \ + {OSSL_FUNC_SIGNATURE_SIGN_MESSAGE_UPDATE, (void (*)(void))p_scossl_rsa_sigalg_signverify_message_update}, \ + {OSSL_FUNC_SIGNATURE_SIGN_MESSAGE_FINAL, (void (*)(void))p_scossl_rsa_sigalg_sign_message_final}, \ + {OSSL_FUNC_SIGNATURE_VERIFY_INIT, (void (*)(void))p_scossl_rsa_##md##_verify_init}, \ + {OSSL_FUNC_SIGNATURE_VERIFY, (void (*)(void))p_scossl_rsa_sigalg_verify}, \ + {OSSL_FUNC_SIGNATURE_VERIFY_MESSAGE_INIT, (void (*)(void))p_scossl_rsa_##md##_verify_message_init}, \ + {OSSL_FUNC_SIGNATURE_VERIFY_MESSAGE_UPDATE,(void (*)(void))p_scossl_rsa_sigalg_signverify_message_update}, \ + {OSSL_FUNC_SIGNATURE_VERIFY_MESSAGE_FINAL, (void (*)(void))p_scossl_rsa_sigalg_verify_message_final}, \ + {OSSL_FUNC_SIGNATURE_QUERY_KEY_TYPES, (void (*)(void))p_scossl_rsa_sigalg_query_key_types}, \ + {OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, (void (*)(void))p_scossl_rsa_get_ctx_params}, \ + {OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, (void (*)(void))p_scossl_rsa_gettable_ctx_params}, \ + {OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, (void (*)(void))p_scossl_rsa_sigalg_set_ctx_params}, \ + {OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, (void (*)(void))p_scossl_rsa_sigalg_settable_ctx_params}, \ + {0, NULL}}; + +IMPLEMENT_SCOSSL_RSA_SIGALG(sha1, OSSL_DIGEST_NAME_SHA1) +IMPLEMENT_SCOSSL_RSA_SIGALG(sha224, OSSL_DIGEST_NAME_SHA2_224) +IMPLEMENT_SCOSSL_RSA_SIGALG(sha256, OSSL_DIGEST_NAME_SHA2_256) +IMPLEMENT_SCOSSL_RSA_SIGALG(sha384, OSSL_DIGEST_NAME_SHA2_384) +IMPLEMENT_SCOSSL_RSA_SIGALG(sha512, OSSL_DIGEST_NAME_SHA2_512) +IMPLEMENT_SCOSSL_RSA_SIGALG(sha512_224, OSSL_DIGEST_NAME_SHA2_512_224) +IMPLEMENT_SCOSSL_RSA_SIGALG(sha512_256, OSSL_DIGEST_NAME_SHA2_512_256) +IMPLEMENT_SCOSSL_RSA_SIGALG(sha3_224, OSSL_DIGEST_NAME_SHA3_224) +IMPLEMENT_SCOSSL_RSA_SIGALG(sha3_256, OSSL_DIGEST_NAME_SHA3_256) +IMPLEMENT_SCOSSL_RSA_SIGALG(sha3_384, OSSL_DIGEST_NAME_SHA3_384) +IMPLEMENT_SCOSSL_RSA_SIGALG(sha3_512, OSSL_DIGEST_NAME_SHA3_512) + +#ifdef __cplusplus +} +#endif diff --git a/SymCryptProvider/src/signature/p_scossl_rsa_signature.c b/SymCryptProvider/src/signature/p_scossl_rsa_signature.c index 43d0783f..a94cb99f 100644 --- a/SymCryptProvider/src/signature/p_scossl_rsa_signature.c +++ b/SymCryptProvider/src/signature/p_scossl_rsa_signature.c @@ -7,35 +7,13 @@ #include #include -#include "scossl_rsa.h" -#include "p_scossl_rsa.h" -#include "p_scossl_base.h" +#include "p_scossl_rsa_signature.h" #ifdef __cplusplus extern "C" { #endif -typedef struct -{ - SCOSSL_PROV_RSA_KEY_CTX *keyCtx; - UINT8 padding; - int operation; - - // Needed for fetching md - OSSL_LIB_CTX *libctx; - char* propq; - - EVP_MD_CTX *mdctx; - EVP_MD *md; - const OSSL_ITEM *mdInfo; // Informational, must match md if set - BOOL allowMdUpdates; - - // PSS params - BOOL pssRestricted; - const OSSL_ITEM *mgf1MdInfo; // Informational, must match md if set - int cbSalt; - int cbSaltMin; -} SCOSSL_RSA_SIGN_CTX; +static SCOSSL_STATUS p_scossl_rsa_set_ctx_params(_Inout_ SCOSSL_RSA_SIGN_CTX *ctx, _In_ const OSSL_PARAM params[]); #define SCOSSL_RSA_SIGNATURE_GETTABLE_PARAMS \ OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0), \ @@ -81,9 +59,8 @@ static OSSL_ITEM p_scossl_rsa_sign_padding_modes[] = { {RSA_PKCS1_PSS_PADDING, OSSL_PKEY_RSA_PAD_MODE_PSS}, {0, NULL}}; -static SCOSSL_STATUS p_scossl_rsa_set_ctx_params(_Inout_ SCOSSL_RSA_SIGN_CTX *ctx, _In_ const OSSL_PARAM params[]); - -static SCOSSL_RSA_SIGN_CTX *p_scossl_rsa_newctx(_In_ SCOSSL_PROVCTX *provctx, _In_ const char *propq) +_Use_decl_annotations_ +SCOSSL_RSA_SIGN_CTX *p_scossl_rsa_newctx(SCOSSL_PROVCTX *provctx, const char *propq) { SCOSSL_RSA_SIGN_CTX *ctx = OPENSSL_zalloc(sizeof(SCOSSL_RSA_SIGN_CTX)); if (ctx != NULL) @@ -104,7 +81,8 @@ static SCOSSL_RSA_SIGN_CTX *p_scossl_rsa_newctx(_In_ SCOSSL_PROVCTX *provctx, _I return ctx; } -static void p_scossl_rsa_freectx(SCOSSL_RSA_SIGN_CTX *ctx) +_Use_decl_annotations_ +void p_scossl_rsa_freectx(SCOSSL_RSA_SIGN_CTX *ctx) { if (ctx == NULL) return; @@ -112,21 +90,24 @@ static void p_scossl_rsa_freectx(SCOSSL_RSA_SIGN_CTX *ctx) EVP_MD_CTX_free(ctx->mdctx); EVP_MD_free(ctx->md); OPENSSL_free(ctx->propq); + OPENSSL_free(ctx->pbSignature); OPENSSL_free(ctx); } -static SCOSSL_RSA_SIGN_CTX *p_scossl_rsa_dupctx(_In_ SCOSSL_RSA_SIGN_CTX *ctx) +_Use_decl_annotations_ +SCOSSL_RSA_SIGN_CTX *p_scossl_rsa_dupctx(SCOSSL_RSA_SIGN_CTX *ctx) { SCOSSL_RSA_SIGN_CTX *copyCtx = OPENSSL_zalloc(sizeof(SCOSSL_RSA_SIGN_CTX)); if (copyCtx != NULL) { if ((ctx->propq != NULL && ((copyCtx->propq = OPENSSL_strdup(ctx->propq)) == NULL)) || (ctx->mdctx != NULL && ((copyCtx->mdctx = EVP_MD_CTX_dup((const EVP_MD_CTX *)ctx->mdctx)) == NULL)) || - (ctx->md != NULL && !EVP_MD_up_ref(ctx->md))) + (ctx->md != NULL && !EVP_MD_up_ref(ctx->md)) || + (ctx->pbSignature != NULL && ((copyCtx->pbSignature = OPENSSL_memdup(ctx->pbSignature, ctx->cbSignature)) == NULL))) { p_scossl_rsa_freectx(copyCtx); ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); - copyCtx = NULL; + return NULL; } copyCtx->keyCtx = ctx->keyCtx; @@ -136,14 +117,23 @@ static SCOSSL_RSA_SIGN_CTX *p_scossl_rsa_dupctx(_In_ SCOSSL_RSA_SIGN_CTX *ctx) copyCtx->md = ctx->md; copyCtx->cbSalt = ctx->cbSalt; copyCtx->mdInfo = ctx->mdInfo; + copyCtx->allowMdUpdates = ctx->allowMdUpdates; + copyCtx->pssRestricted = ctx->pssRestricted; copyCtx->mgf1MdInfo = ctx->mgf1MdInfo; + copyCtx->cbSaltMin = ctx->cbSaltMin; + copyCtx->isSigalg = ctx->isSigalg; + copyCtx->allowUpdate = ctx->allowUpdate; + copyCtx->allowFinal = ctx->allowFinal; + copyCtx->allowOneshot = ctx->allowOneshot; + copyCtx->cbSignature = ctx->cbSignature; } return copyCtx; } -static SCOSSL_STATUS p_scossl_rsa_signverify_init(_Inout_ SCOSSL_RSA_SIGN_CTX *ctx, _In_ SCOSSL_PROV_RSA_KEY_CTX *keyCtx, - _In_ const OSSL_PARAM params[], int operation) +_Use_decl_annotations_ +SCOSSL_STATUS p_scossl_rsa_signverify_init(SCOSSL_RSA_SIGN_CTX *ctx, SCOSSL_PROV_RSA_KEY_CTX *keyCtx, + const OSSL_PARAM params[], int operation) { if (ctx == NULL || (keyCtx == NULL && ctx->keyCtx == NULL)) @@ -152,12 +142,20 @@ static SCOSSL_STATUS p_scossl_rsa_signverify_init(_Inout_ SCOSSL_RSA_SIGN_CTX *c return SCOSSL_FAILURE; } -#ifdef RSA_PSS_SALTLEN_AUTO_DIGEST_MAX ctx->cbSalt = RSA_PSS_SALTLEN_AUTO_DIGEST_MAX; -#else - ctx->cbSalt = RSA_PSS_SALTLEN_AUTO; -#endif + ctx->cbSaltMin = -1; ctx->operation = operation; + ctx->allowMdUpdates = TRUE; + ctx->allowUpdate = TRUE; + ctx->allowFinal = TRUE; + ctx->allowOneshot = TRUE; + ctx->isSigalg = FALSE; + ctx->pssRestricted = FALSE; + + OPENSSL_free(ctx->pbSignature); + ctx->pbSignature = NULL; + ctx->cbSignature = 0; + if (keyCtx != NULL) { if (!keyCtx->initialized) @@ -199,7 +197,7 @@ static SCOSSL_STATUS p_scossl_rsa_signverify_init(_Inout_ SCOSSL_RSA_SIGN_CTX *c #ifdef KEYSINUSE_ENABLED if (keysinuse_is_running() && - operation == EVP_PKEY_OP_SIGN) + (operation == EVP_PKEY_OP_SIGN || operation == EVP_PKEY_OP_SIGNMSG)) { p_scossl_rsa_init_keysinuse(keyCtx); } @@ -221,9 +219,10 @@ static SCOSSL_STATUS p_scossl_rsa_verify_init(_Inout_ SCOSSL_RSA_SIGN_CTX *ctx, return p_scossl_rsa_signverify_init(ctx, keyCtx, params, EVP_PKEY_OP_VERIFY); } -static SCOSSL_STATUS p_scossl_rsa_sign(_In_ SCOSSL_RSA_SIGN_CTX *ctx, - _Out_writes_bytes_(*siglen) unsigned char *sig, _Out_ size_t *siglen, size_t sigsize, - _In_reads_bytes_(tbslen) const unsigned char *tbs, size_t tbslen) +_Use_decl_annotations_ +SCOSSL_STATUS p_scossl_rsa_sign_internal(SCOSSL_RSA_SIGN_CTX *ctx, + unsigned char *sig, size_t *siglen, size_t sigsize, + const unsigned char *tbs, size_t tbslen) { int mdnid = ctx->mdInfo == NULL ? NID_undef : ctx->mdInfo->id; SCOSSL_STATUS ret = SCOSSL_FAILURE; @@ -234,12 +233,6 @@ static SCOSSL_STATUS p_scossl_rsa_sign(_In_ SCOSSL_RSA_SIGN_CTX *ctx, return SCOSSL_FAILURE; } - if (ctx->operation != EVP_PKEY_OP_SIGN) - { - ERR_raise(ERR_LIB_PROV, ERR_R_OPERATION_FAIL); - return SCOSSL_FAILURE; - } - if (sig != NULL && sigsize < SymCryptRsakeySizeofModulus(ctx->keyCtx->key)) { ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); @@ -276,9 +269,10 @@ static SCOSSL_STATUS p_scossl_rsa_sign(_In_ SCOSSL_RSA_SIGN_CTX *ctx, return ret; } -static SCOSSL_STATUS p_scossl_rsa_verify(_In_ SCOSSL_RSA_SIGN_CTX *ctx, - _In_reads_bytes_(siglen) const unsigned char *sig, size_t siglen, - _In_reads_bytes_(tbslen) const unsigned char *tbs, size_t tbslen) +_Use_decl_annotations_ +SCOSSL_STATUS p_scossl_rsa_verify_internal(SCOSSL_RSA_SIGN_CTX *ctx, + const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen) { int mdnid = ctx->mdInfo == NULL ? NID_undef : ctx->mdInfo->id; @@ -288,12 +282,6 @@ static SCOSSL_STATUS p_scossl_rsa_verify(_In_ SCOSSL_RSA_SIGN_CTX *ctx, return SCOSSL_FAILURE; } - if (ctx->operation != EVP_PKEY_OP_VERIFY) - { - ERR_raise(ERR_LIB_PROV, ERR_R_OPERATION_FAIL); - return SCOSSL_FAILURE; - } - switch (ctx->padding) { case RSA_PKCS1_PADDING: @@ -312,7 +300,6 @@ static SCOSSL_STATUS p_scossl_rsa_verify(_In_ SCOSSL_RSA_SIGN_CTX *ctx, return SCOSSL_FAILURE; } - static SCOSSL_STATUS p_scossl_rsa_digest_signverify_init(_In_ SCOSSL_RSA_SIGN_CTX *ctx, _In_ const char *mdname, _In_ SCOSSL_PROV_RSA_KEY_CTX *keyCtx, _In_ const OSSL_PARAM params[], int operation) { @@ -381,57 +368,163 @@ static SCOSSL_STATUS p_scossl_rsa_digest_verify_init(_In_ SCOSSL_RSA_SIGN_CTX *c static SCOSSL_STATUS p_scossl_rsa_digest_signverify_update(_In_ SCOSSL_RSA_SIGN_CTX *ctx, _In_reads_bytes_(datalen) const unsigned char *data, size_t datalen) { - if (ctx->mdctx == NULL) + if (ctx == NULL || ctx->mdctx == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); return SCOSSL_FAILURE; } + if (ctx->isSigalg) + { + ERR_raise(ERR_LIB_PROV, PROV_R_NOT_SUPPORTED); + return SCOSSL_FAILURE; + } + + if (!ctx->allowUpdate) + { + ERR_raise(ERR_LIB_PROV, PROV_R_UPDATE_CALL_OUT_OF_ORDER); + return SCOSSL_FAILURE; + } + + ctx->allowOneshot = FALSE; + return EVP_DigestUpdate(ctx->mdctx, data, datalen); } static SCOSSL_STATUS p_scossl_rsa_digest_sign_final(_In_ SCOSSL_RSA_SIGN_CTX *ctx, - _Out_writes_bytes_(*siglen) unsigned char *sig, _Out_ size_t *siglen, size_t sigsize) + _Out_writes_bytes_opt_(*siglen) unsigned char *sig, _Out_ size_t *siglen, size_t sigsize) { SCOSSL_STATUS ret = SCOSSL_FAILURE; BYTE digest[EVP_MAX_MD_SIZE]; unsigned int cbDigest = 0; - if (ctx->mdctx == NULL) + if (ctx == NULL || ctx->mdctx == NULL) { - return ret; + ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); + return SCOSSL_FAILURE; + } + + if (ctx->isSigalg) + { + ERR_raise(ERR_LIB_PROV, PROV_R_NOT_SUPPORTED); + return SCOSSL_FAILURE; + } + + if (!ctx->allowFinal) + { + ERR_raise(ERR_LIB_PROV, PROV_R_FINAL_CALL_OUT_OF_ORDER); + return SCOSSL_FAILURE; } // If sig is NULL, this is a size fetch, and the digest does not need to be computed - if (sig == NULL || EVP_DigestFinal(ctx->mdctx, digest, &cbDigest)) + if (sig != NULL) { - ctx->allowMdUpdates = sig != NULL; - ret = p_scossl_rsa_sign(ctx, sig, siglen, sigsize, digest, cbDigest); + ctx->allowMdUpdates = TRUE; + + if (!EVP_DigestFinal_ex(ctx->mdctx, digest, &cbDigest)) + { + return SCOSSL_FAILURE; + } + + ctx->allowUpdate = FALSE; + ctx->allowFinal = FALSE; + ctx->allowOneshot = FALSE; } + ret = p_scossl_rsa_sign_internal(ctx, sig, siglen, sigsize, digest, cbDigest); + + return ret; } static SCOSSL_STATUS p_scossl_rsa_digest_verify_final(_In_ SCOSSL_RSA_SIGN_CTX *ctx, _In_reads_bytes_(siglen) unsigned char *sig, size_t siglen) { + SCOSSL_STATUS ret = SCOSSL_FAILURE; BYTE digest[EVP_MAX_MD_SIZE]; unsigned int cbDigest = 0; - if (ctx->mdctx == NULL) + if (ctx == NULL || ctx->mdctx == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); return SCOSSL_FAILURE; } + if (ctx->isSigalg) + { + ERR_raise(ERR_LIB_PROV, PROV_R_NOT_SUPPORTED); + return SCOSSL_FAILURE; + } + + if (!ctx->allowFinal) + { + ERR_raise(ERR_LIB_PROV, PROV_R_FINAL_CALL_OUT_OF_ORDER); + return SCOSSL_FAILURE; + } + + if (!EVP_DigestFinal_ex(ctx->mdctx, digest, &cbDigest)) + { + return SCOSSL_FAILURE; + } + + ctx->allowUpdate = FALSE; + ctx->allowFinal = FALSE; + ctx->allowOneshot = FALSE; + + ret = p_scossl_rsa_verify_internal(ctx, sig, siglen, digest, cbDigest); + ctx->allowMdUpdates = TRUE; - return EVP_DigestFinal(ctx->mdctx, digest, &cbDigest) && - p_scossl_rsa_verify(ctx, sig, siglen, digest, cbDigest); + return ret; +} + +static SCOSSL_STATUS p_scossl_rsa_sign(_In_ SCOSSL_RSA_SIGN_CTX *ctx, + _Out_writes_bytes_opt_(*siglen) unsigned char *sig, _Out_ size_t *siglen, size_t sigsize, + _In_reads_bytes_(tbslen) const unsigned char *tbs, size_t tbslen) +{ + if (ctx == NULL) + { + ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET); + return SCOSSL_FAILURE; + } + + if (!ctx->allowOneshot) + { + ERR_raise(ERR_LIB_PROV, PROV_R_ONESHOT_CALL_OUT_OF_ORDER); + return SCOSSL_FAILURE; + } + + return p_scossl_rsa_sign_internal(ctx, sig, siglen, sigsize, tbs, tbslen); +} + +static SCOSSL_STATUS p_scossl_rsa_verify(_In_ SCOSSL_RSA_SIGN_CTX *ctx, + _In_reads_bytes_(siglen) const unsigned char *sig, size_t siglen, + _In_reads_bytes_(tbslen) const unsigned char *tbs, size_t tbslen) +{ + if (ctx == NULL) + { + ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET); + return SCOSSL_FAILURE; + } + + if (!ctx->allowOneshot) + { + ERR_raise(ERR_LIB_PROV, PROV_R_ONESHOT_CALL_OUT_OF_ORDER); + return SCOSSL_FAILURE; + } + + return p_scossl_rsa_verify_internal(ctx, sig, siglen, tbs, tbslen); } static const OSSL_PARAM *p_scossl_rsa_settable_ctx_params(_In_ SCOSSL_RSA_SIGN_CTX *ctx, ossl_unused void *provctx) { - return ctx->allowMdUpdates ? p_scossl_rsa_sig_ctx_settable_param_types : p_scossl_rsa_sig_ctx_settable_param_types_no_digest; + if (ctx != NULL && !ctx->allowMdUpdates) + { + return p_scossl_rsa_sig_ctx_settable_param_types_no_digest; + } + + return p_scossl_rsa_sig_ctx_settable_param_types; } static SCOSSL_STATUS p_scossl_rsa_set_ctx_params(_Inout_ SCOSSL_RSA_SIGN_CTX *ctx, _In_ const OSSL_PARAM params[]) @@ -581,14 +674,12 @@ static SCOSSL_STATUS p_scossl_rsa_set_ctx_params(_Inout_ SCOSSL_RSA_SIGN_CTX *ct { cbSalt = RSA_PSS_SALTLEN_MAX; } -#ifdef RSA_PSS_SALTLEN_AUTO_DIGEST_MAX else if (strcmp(p->data, OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO_DIGEST_MAX) == 0) { // Sign: Smaller of digest length or maximized salt length // Verify: Autorecovered salt length cbSalt = RSA_PSS_SALTLEN_AUTO_DIGEST_MAX; } -#endif else { cbSalt = atoi(p->data); @@ -598,11 +689,7 @@ static SCOSSL_STATUS p_scossl_rsa_set_ctx_params(_Inout_ SCOSSL_RSA_SIGN_CTX *ct ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); return SCOSSL_FAILURE; } -#ifdef RSA_PSS_SALTLEN_AUTO_DIGEST_MAX if (cbSalt < RSA_PSS_SALTLEN_AUTO_DIGEST_MAX) -#else - if (cbSalt < RSA_PSS_SALTLEN_MAX) -#endif { ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH); return SCOSSL_FAILURE; @@ -613,10 +700,9 @@ static SCOSSL_STATUS p_scossl_rsa_set_ctx_params(_Inout_ SCOSSL_RSA_SIGN_CTX *ct switch (cbSalt) { case RSA_PSS_SALTLEN_AUTO: -#ifdef RSA_PSS_SALTLEN_AUTO_DIGEST_MAX case RSA_PSS_SALTLEN_AUTO_DIGEST_MAX: -#endif - if (ctx->operation == EVP_PKEY_OP_VERIFY) + if (ctx->operation == EVP_PKEY_OP_VERIFY || + ctx->operation == EVP_PKEY_OP_VERIFYMSG) { ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH); return SCOSSL_FAILURE; @@ -699,8 +785,8 @@ static SCOSSL_STATUS p_scossl_rsa_set_ctx_params(_Inout_ SCOSSL_RSA_SIGN_CTX *ct return SCOSSL_SUCCESS; } -static const OSSL_PARAM *p_scossl_rsa_gettable_ctx_params(_In_ SCOSSL_RSA_SIGN_CTX *ctx, - ossl_unused void *provctx) +_Use_decl_annotations_ +const OSSL_PARAM *p_scossl_rsa_gettable_ctx_params(SCOSSL_RSA_SIGN_CTX *ctx, ossl_unused void *provctx) { return ctx->padding == RSA_PKCS1_PSS_PADDING ? p_scossl_rsa_pss_sig_ctx_gettable_param_types : p_scossl_rsa_sig_ctx_gettable_param_types; } @@ -768,11 +854,9 @@ static ASN1_STRING *p_scossl_rsa_pss_params_to_asn1_sequence(_In_ SCOSSL_RSA_SIG case RSA_PSS_SALTLEN_AUTO: cbSalt = cbSaltMax; break; -#ifdef RSA_PSS_SALTLEN_AUTO_DIGEST_MAX case RSA_PSS_SALTLEN_AUTO_DIGEST_MAX: cbSalt = cbSaltMax < (int)cbHash ? cbSaltMax : (int)cbHash; break; -#endif } if (cbSalt < 0) @@ -805,7 +889,8 @@ static ASN1_STRING *p_scossl_rsa_pss_params_to_asn1_sequence(_In_ SCOSSL_RSA_SIG return pssParamSeq; } -static SCOSSL_STATUS p_scossl_rsa_get_ctx_params(_In_ SCOSSL_RSA_SIGN_CTX *ctx, _Inout_ OSSL_PARAM params[]) +_Use_decl_annotations_ +SCOSSL_STATUS p_scossl_rsa_get_ctx_params(SCOSSL_RSA_SIGN_CTX *ctx, OSSL_PARAM params[]) { if (params == NULL) { @@ -981,11 +1066,9 @@ static SCOSSL_STATUS p_scossl_rsa_get_ctx_params(_In_ SCOSSL_RSA_SIGN_CTX *ctx, case RSA_PSS_SALTLEN_MAX: saltLenText = OSSL_PKEY_RSA_PSS_SALT_LEN_MAX; break; -#ifdef RSA_PSS_SALTLEN_AUTO_DIGEST_MAX case RSA_PSS_SALTLEN_AUTO_DIGEST_MAX: saltLenText = OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO_DIGEST_MAX; break; -#endif default: len = BIO_snprintf(p->data, p->data_size, "%d", ctx->cbSalt); diff --git a/SymCryptProvider/src/signature/p_scossl_rsa_signature.h b/SymCryptProvider/src/signature/p_scossl_rsa_signature.h new file mode 100644 index 00000000..db3f8263 --- /dev/null +++ b/SymCryptProvider/src/signature/p_scossl_rsa_signature.h @@ -0,0 +1,69 @@ +// +// Copyright (c) Microsoft Corporation. Licensed under the MIT license. +// + +#pragma once + +#include +#include + +#include "scossl_rsa.h" +#include "p_scossl_rsa.h" +#include "p_scossl_base.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct +{ + SCOSSL_PROV_RSA_KEY_CTX *keyCtx; + UINT8 padding; + int operation; + + // Needed for fetching md + OSSL_LIB_CTX *libctx; + char* propq; + + EVP_MD_CTX *mdctx; + EVP_MD *md; + const OSSL_ITEM *mdInfo; // Informational, must match md if set + BOOL allowMdUpdates; + + // PSS params + BOOL pssRestricted; + const OSSL_ITEM *mgf1MdInfo; // Informational, must match md if set + int cbSalt; + int cbSaltMin; + + // Sigalg state tracking + BOOL isSigalg; + BOOL allowUpdate; + BOOL allowFinal; + BOOL allowOneshot; + + // Sigalg verify message support + PBYTE pbSignature; + SIZE_T cbSignature; +} SCOSSL_RSA_SIGN_CTX; + +SCOSSL_RSA_SIGN_CTX *p_scossl_rsa_newctx(_In_ SCOSSL_PROVCTX *provctx, _In_ const char *propq); +void p_scossl_rsa_freectx(_Inout_ SCOSSL_RSA_SIGN_CTX *ctx); +SCOSSL_RSA_SIGN_CTX *p_scossl_rsa_dupctx(_In_ SCOSSL_RSA_SIGN_CTX *ctx); + +SCOSSL_STATUS p_scossl_rsa_signverify_init(_Inout_ SCOSSL_RSA_SIGN_CTX *ctx, _In_ SCOSSL_PROV_RSA_KEY_CTX *keyCtx, + _In_ const OSSL_PARAM params[], int operation); + +SCOSSL_STATUS p_scossl_rsa_sign_internal(_In_ SCOSSL_RSA_SIGN_CTX *ctx, + _Out_writes_bytes_opt_(*siglen) unsigned char *sig, _Out_ size_t *siglen, size_t sigsize, + _In_reads_bytes_(tbslen) const unsigned char *tbs, size_t tbslen); +SCOSSL_STATUS p_scossl_rsa_verify_internal(_In_ SCOSSL_RSA_SIGN_CTX *ctx, + _In_reads_bytes_(siglen) const unsigned char *sig, size_t siglen, + _In_reads_bytes_(tbslen) const unsigned char *tbs, size_t tbslen); + +const OSSL_PARAM *p_scossl_rsa_gettable_ctx_params(_In_ SCOSSL_RSA_SIGN_CTX *ctx, ossl_unused void *provctx); +SCOSSL_STATUS p_scossl_rsa_get_ctx_params(_In_ SCOSSL_RSA_SIGN_CTX *ctx, _Inout_ OSSL_PARAM params[]); + +#ifdef __cplusplus +} +#endif