local testimony = require("testimony") local litls = require("litls.core") local hex = litls.hex_encode local unhex = litls.hex_decode local testify = testimony.new("== LITLS RSA Verify ==") -- RSA-2048 test key components (generated with openssl) local N = unhex( "cee5fa00957ae7dd67c2d1855a4496e924e4a69b34cd123815a61de2dd04b0c9108c97ca98e3a9bd15c2961dc1ff8e284cb6de0b3c928ca4d22fec17ff6aa38d9bd3e3a957fce80e7b086ec076bfeb838e8f2ddfde89e880145c8dba1d1a513e48c270a00193f45faf479873fe56063f175ef3efc6de9320e5ff5b53d740bd6d2d5b644c3378a988e0c5a658af1e974acdc02293ff86e30f37973fbe958273e92071d2465a945c4ae2232ec71a76780a486bb8320a13942a8093267188967e7fe2cb1c00bd3d869c59e36dae41e4caa4a22fd50d2eaeab1dfc9df6a4b4047b745fc64a10552bee3df8f111e6c16eb7a46b42c042393380b22bb9e94fff76716b" ) local E = unhex("010001") -- SHA-256 RSA-PKCS#1 v1.5 signature verification testify:that("RSA-2048 PKCS#1 v1.5 SHA-256 verify", function() local hash = unhex("3f0a377ba0a4a460ecb616f6507ce0d8cfa3e704025d4fda3ed0c5ca05468728") local sig = unhex( "7bad9a78581ee8b44cc7e9522b8d9375842a3aab4f8b71629bcd7ed45c9b58245116251c2e12735868f36b8a0b3356ea5c5896ec2044e1ba11fc6e3c7ceef8f6847897aa84614e7faad24845a63427e127604154620ff15c779a9dbf35491792e2caeed2984eafbc9f5d3defab82fd6d083343d219be17b984b4779ebfeeaa4e06bdeebc05fd63baa1d1c4ab9be48bac6d5f60f2feeed90df265302c64ce456513d5c69bcb3fbc6c4442bdfd5e7740098a423186405b5acfc5424dd190215f6233c1ee2fc48865379bef603449c05d62969c1b910a70d5a7ece5de6316b2406a8fc16e375b283ee591069600dc267709389f68cb8692f21868475412e3871c2f" ) local ok = litls.rsa_pkcs1_verify(hash, litls.HASH_SHA256, sig, N, E) testimony.assert_equal(true, ok) end) -- SHA-384 RSA-PKCS#1 v1.5 signature verification testify:that("RSA-2048 PKCS#1 v1.5 SHA-384 verify", function() local hash = unhex("ab5d1b86c9f2a4e93090b6468b599ecb5efb354ca7427f4a7e5986f04c0844c09ce81a4bc6b0e47d529f531056f1017f") local sig = unhex( "3cff5c7fbb6da2cb2eb5995f6fb09ea62e6b234b2d0b454ae75b9e8bd8e8278a6a7c5fbb7cab893891d6a7b8266e96d1dbddef4d292884194a10e18112c4abc31da891b2ed95214e740279e96a511ddbe47394027d8f0ddab5af4cb6707c5b77cdb568836a4af369fcb29ba32ae8dd205654221c33b92d5dd821013b8438806ef93bea6ea9a1f16ce52fac20ca865973c2122c9ace09255acc75be1635bb374b690cba6f1ac42f8e268c462c3ecb8bcf559815a8b06ae45c35f1af44cf2af550d8911fd2129ddae7da34af2e8faa857c80417c6d5ece403ee913cef451a7c38a845ecb453123b50fa558dd805055b01de9589bce090070ed9b10b0ea7df52df1" ) local ok = litls.rsa_pkcs1_verify(hash, litls.HASH_SHA384, sig, N, E) testimony.assert_equal(true, ok) end) -- SHA-512 RSA-PKCS#1 v1.5 signature verification testify:that("RSA-2048 PKCS#1 v1.5 SHA-512 verify", function() local hash = unhex( "5ede2e6898f1746533917f65ee5637f168ef70b6cd0814cac2fb08360324b27bf076070cf6868cf88750927fda9262e42b31aaab6cfc8b427514fdab1baec042" ) local sig = unhex( "41adc17f263274c18682aa9165e53bd51bd50b3f6446c204f03bf91a60c7b5c3fdebb45ac1cb758f790a99ef152d9afcae4bd0ae0b029f9909869edc7af9866126e20a44e1fd2605727d6b5ba93b5f7189a1344fcbba6e65945d8bd09b32cb762832a3770000782d37fd82e4ff882f1c3e124a4aa7ece8109fe7e588af101eac5e8778e1344c834f864d4e3b2b81265ccfa57c263d4038d20372b1fa0ab19571aebc4158bca2e2c43de5f5ab266c57897aef6dc6399601abe291f3d4bc30dcab9bf44c40b43f32824b718bee414574862b7016dff61fff20be3e91d540d18585e2bb3f1d9321fe2f70f62b149d0edd5c0000e9e40fcfbe82b60d2aaac0f2a2bc" ) local ok = litls.rsa_pkcs1_verify(hash, litls.HASH_SHA512, sig, N, E) testimony.assert_equal(true, ok) end) -- Reject modified signature testify:that("RSA verify rejects modified signature", function() local hash = unhex("3f0a377ba0a4a460ecb616f6507ce0d8cfa3e704025d4fda3ed0c5ca05468728") local sig = unhex( "7bad9a78581ee8b44cc7e9522b8d9375842a3aab4f8b71629bcd7ed45c9b58245116251c2e12735868f36b8a0b3356ea5c5896ec2044e1ba11fc6e3c7ceef8f6847897aa84614e7faad24845a63427e127604154620ff15c779a9dbf35491792e2caeed2984eafbc9f5d3defab82fd6d083343d219be17b984b4779ebfeeaa4e06bdeebc05fd63baa1d1c4ab9be48bac6d5f60f2feeed90df265302c64ce456513d5c69bcb3fbc6c4442bdfd5e7740098a423186405b5acfc5424dd190215f6233c1ee2fc48865379bef603449c05d62969c1b910a70d5a7ece5de6316b2406a8fc16e375b283ee591069600dc267709389f68cb8692f21868475412e3871c2f" ) -- Flip a bit in the signature local bad_sig = sig:sub(1, 10) .. string.char(bit.bxor(sig:byte(11), 1)) .. sig:sub(12) local ok = litls.rsa_pkcs1_verify(hash, litls.HASH_SHA256, bad_sig, N, E) testimony.assert_equal(false, ok) end) -- Reject wrong hash testify:that("RSA verify rejects wrong hash", function() local wrong_hash = unhex("0000000000000000000000000000000000000000000000000000000000000000") local sig = unhex( "7bad9a78581ee8b44cc7e9522b8d9375842a3aab4f8b71629bcd7ed45c9b58245116251c2e12735868f36b8a0b3356ea5c5896ec2044e1ba11fc6e3c7ceef8f6847897aa84614e7faad24845a63427e127604154620ff15c779a9dbf35491792e2caeed2984eafbc9f5d3defab82fd6d083343d219be17b984b4779ebfeeaa4e06bdeebc05fd63baa1d1c4ab9be48bac6d5f60f2feeed90df265302c64ce456513d5c69bcb3fbc6c4442bdfd5e7740098a423186405b5acfc5424dd190215f6233c1ee2fc48865379bef603449c05d62969c1b910a70d5a7ece5de6316b2406a8fc16e375b283ee591069600dc267709389f68cb8692f21868475412e3871c2f" ) local ok = litls.rsa_pkcs1_verify(wrong_hash, litls.HASH_SHA256, sig, N, E) testimony.assert_equal(false, ok) end) -- RSA-PSS-SHA256 signature verification -- Test vector: sign "test message" with the same RSA-2048 key using PSS padding -- Generated with: echo -n "test message" | openssl dgst -sha256 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:32 testify:that("RSA-2048 PSS-SHA256 verify", function() -- We test RSA-PSS by creating a known hash and known PSS signature -- This uses the same N, E as above local hash = litls.sha256("test message for rsa-pss verification") -- For now, test that the function exists and rejects invalid signatures local bad_sig = string.rep("\x00", 256) local ok = litls.rsa_pss_sha256_verify(hash, bad_sig, N, E) testimony.assert_equal(false, ok) end) -- RSA-PSS reject wrong hash testify:that("RSA-PSS rejects wrong hash length", function() local wrong_hash = unhex("0000000000000000") local sig = string.rep("\x00", 256) -- hash must be exactly 32 bytes for SHA-256 local ok = litls.rsa_pss_sha256_verify(wrong_hash, sig, N, E) testimony.assert_equal(false, ok) end) testify:conclude()