blob: 555e1fb19d129f01f1dcb2d1af78995f46ab009d [file] [log] [blame]
# -*- coding: utf-8 -*-
#
# SelfTest/Signature/test_pkcs1_pss.py: Self-test for PKCS#1 PSS signatures
#
# ===================================================================
# The contents of this file are dedicated to the public domain. To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
from __future__ import nested_scopes
__revision__ = "$Id$"
import unittest
from Crypto.PublicKey import RSA
from Crypto import Random
from Crypto.SelfTest.st_common import list_test_cases, a2b_hex, b2a_hex
from Crypto.Hash import *
from Crypto.Signature import PKCS1_PSS as PKCS
from Crypto.Util.py3compat import *
def isStr(s):
t = ''
try:
t += s
except TypeError:
return 0
return 1
def rws(t):
"""Remove white spaces, tabs, and new lines from a string"""
for c in ['\t', '\n', ' ']:
t = t.replace(c,'')
return t
def t2b(t):
"""Convert a text string with bytes in hex form to a byte string"""
clean = b(rws(t))
if len(clean)%2 == 1:
raise ValueError("Even number of characters expected")
return a2b_hex(clean)
# dump str to bytes
def rsa_dump(data):
print("-----------pss_mytest dump:----------")
for i in range(0, len(data)):
print ("0x%02x,"%ord(data[i])),
if(((i+1)%16) == 0):
print("")
print("-----------pss_mytest dump end-----------")
# Helper class to count how many bytes have been requested
# from the key's private RNG, w/o counting those used for blinding
class MyKey:
def __init__(self, key):
self._key = key
self.n = key.n
self.asked = 0
def _randfunc(self, N):
self.asked += N
return self._key._randfunc(N)
def sign(self, m):
return self._key.sign(m)
def has_private(self):
return self._key.has_private()
def decrypt(self, m):
return self._key.decrypt(m)
def verify(self, m, p):
return self._key.verify(m, p)
def encrypt(self, m, p):
return self._key.encrypt(m, p)
class PKCS1_PSS_Tests(unittest.TestCase):
# List of tuples with test data for PKCS#1 PSS
# Each tuple is made up by:
# Item #0: dictionary with RSA key component, or key to import
# Item #1: data to hash and sign
# Item #2: signature of the data #1, done with the key #0,
# and salt #3 after hashing it with #4
# Item #3: salt
# Item #4: hash object generator
_testData = (
#
# From in pss-vect.txt to be found in
# ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip
#
(
# Private key
{
'n':'''a2 ba 40 ee 07 e3 b2 bd 2f 02 ce 22 7f 36 a1 95
02 44 86 e4 9c 19 cb 41 bb bd fb ba 98 b2 2b 0e
57 7c 2e ea ff a2 0d 88 3a 76 e6 5e 39 4c 69 d4
b3 c0 5a 1e 8f ad da 27 ed b2 a4 2b c0 00 fe 88
8b 9b 32 c2 2d 15 ad d0 cd 76 b3 e7 93 6e 19 95
5b 22 0d d1 7d 4e a9 04 b1 ec 10 2b 2e 4d e7 75
12 22 aa 99 15 10 24 c7 cb 41 cc 5e a2 1d 00 ee
b4 1f 7c 80 08 34 d2 c6 e0 6b ce 3b ce 7e a9 a5''',
'e':'''01 00 01''',
# In the test vector, only p and q were given...
# d is computed offline as e^{-1} mod (p-1)(q-1)
'd':'''50e2c3e38d886110288dfc68a9533e7e12e27d2aa56
d2cdb3fb6efa990bcff29e1d2987fb711962860e7391b1ce01
ebadb9e812d2fbdfaf25df4ae26110a6d7a26f0b810f54875e
17dd5c9fb6d641761245b81e79f8c88f0e55a6dcd5f133abd3
5f8f4ec80adf1bf86277a582894cb6ebcd2162f1c7534f1f49
47b129151b71'''
},
# Data to sign
'''85 9e ef 2f d7 8a ca 00 30 8b dc 47 11 93 bf 55
bf 9d 78 db 8f 8a 67 2b 48 46 34 f3 c9 c2 6e 64
78 ae 10 26 0f e0 dd 8c 08 2e 53 a5 29 3a f2 17
3c d5 0c 6d 5d 35 4f eb f7 8b 26 02 1c 25 c0 27
12 e7 8c d4 69 4c 9f 46 97 77 e4 51 e7 f8 e9 e0
4c d3 73 9c 6b bf ed ae 48 7f b5 56 44 e9 ca 74
ff 77 a5 3c b7 29 80 2f 6e d4 a5 ff a8 ba 15 98
90 fc''',
# Signature
'''8d aa 62 7d 3d e7 59 5d 63 05 6c 7e c6 59 e5 44
06 f1 06 10 12 8b aa e8 21 c8 b2 a0 f3 93 6d 54
dc 3b dc e4 66 89 f6 b7 95 1b b1 8e 84 05 42 76
97 18 d5 71 5d 21 0d 85 ef bb 59 61 92 03 2c 42
be 4c 29 97 2c 85 62 75 eb 6d 5a 45 f0 5f 51 87
6f c6 74 3d ed dd 28 ca ec 9b b3 0e a9 9e 02 c3
48 82 69 60 4f e4 97 f7 4c cd 7c 7f ca 16 71 89
71 23 cb d3 0d ef 5d 54 a2 b5 53 6a d9 0a 74 7e''',
# Salt
'''e3 b5 d5 d0 02 c1 bc e5 0c 2b 65 ef 88 a1 88 d8
3b ce 7e 61''',
# Hash algorithm
SHA
),
#
# Example 1.1 to be found in
# ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip
#
(
# Private key
{
'n':'''a5 6e 4a 0e 70 10 17 58 9a 51 87 dc 7e a8 41 d1
56 f2 ec 0e 36 ad 52 a4 4d fe b1 e6 1f 7a d9 91
d8 c5 10 56 ff ed b1 62 b4 c0 f2 83 a1 2a 88 a3
94 df f5 26 ab 72 91 cb b3 07 ce ab fc e0 b1 df
d5 cd 95 08 09 6d 5b 2b 8b 6d f5 d6 71 ef 63 77
c0 92 1c b2 3c 27 0a 70 e2 59 8e 6f f8 9d 19 f1
05 ac c2 d3 f0 cb 35 f2 92 80 e1 38 6b 6f 64 c4
ef 22 e1 e1 f2 0d 0c e8 cf fb 22 49 bd 9a 21 37''',
'e':'''01 00 01''',
'd':'''33 a5 04 2a 90 b2 7d 4f 54 51 ca 9b bb d0 b4 47
71 a1 01 af 88 43 40 ae f9 88 5f 2a 4b be 92 e8
94 a7 24 ac 3c 56 8c 8f 97 85 3a d0 7c 02 66 c8
c6 a3 ca 09 29 f1 e8 f1 12 31 88 44 29 fc 4d 9a
e5 5f ee 89 6a 10 ce 70 7c 3e d7 e7 34 e4 47 27
a3 95 74 50 1a 53 26 83 10 9c 2a ba ca ba 28 3c
31 b4 bd 2f 53 c3 ee 37 e3 52 ce e3 4f 9e 50 3b
d8 0c 06 22 ad 79 c6 dc ee 88 35 47 c6 a3 b3 25'''
},
# Message
'''cd c8 7d a2 23 d7 86 df 3b 45 e0 bb bc 72 13 26
d1 ee 2a f8 06 cc 31 54 75 cc 6f 0d 9c 66 e1 b6
23 71 d4 5c e2 39 2e 1a c9 28 44 c3 10 10 2f 15
6a 0d 8d 52 c1 f4 c4 0b a3 aa 65 09 57 86 cb 76
97 57 a6 56 3b a9 58 fe d0 bc c9 84 e8 b5 17 a3
d5 f5 15 b2 3b 8a 41 e7 4a a8 67 69 3f 90 df b0
61 a6 e8 6d fa ae e6 44 72 c0 0e 5f 20 94 57 29
cb eb e7 7f 06 ce 78 e0 8f 40 98 fb a4 1f 9d 61
93 c0 31 7e 8b 60 d4 b6 08 4a cb 42 d2 9e 38 08
a3 bc 37 2d 85 e3 31 17 0f cb f7 cc 72 d0 b7 1c
29 66 48 b3 a4 d1 0f 41 62 95 d0 80 7a a6 25 ca
b2 74 4f d9 ea 8f d2 23 c4 25 37 02 98 28 bd 16
be 02 54 6f 13 0f d2 e3 3b 93 6d 26 76 e0 8a ed
1b 73 31 8b 75 0a 01 67 d0''',
# Signature
'''90 74 30 8f b5 98 e9 70 1b 22 94 38 8e 52 f9 71
fa ac 2b 60 a5 14 5a f1 85 df 52 87 b5 ed 28 87
e5 7c e7 fd 44 dc 86 34 e4 07 c8 e0 e4 36 0b c2
26 f3 ec 22 7f 9d 9e 54 63 8e 8d 31 f5 05 12 15
df 6e bb 9c 2f 95 79 aa 77 59 8a 38 f9 14 b5 b9
c1 bd 83 c4 e2 f9 f3 82 a0 d0 aa 35 42 ff ee 65
98 4a 60 1b c6 9e b2 8d eb 27 dc a1 2c 82 c2 d4
c3 f6 6c d5 00 f1 ff 2b 99 4d 8a 4e 30 cb b3 3c''',
# Salt
'''de e9 59 c7 e0 64 11 36 14 20 ff 80 18 5e d5 7f
3e 67 76 af''',
# Hash
SHA
),
#
# Example 1.2 to be found in
# ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip
#
(
# Private key
{
'n':'''a5 6e 4a 0e 70 10 17 58 9a 51 87 dc 7e a8 41 d1
56 f2 ec 0e 36 ad 52 a4 4d fe b1 e6 1f 7a d9 91
d8 c5 10 56 ff ed b1 62 b4 c0 f2 83 a1 2a 88 a3
94 df f5 26 ab 72 91 cb b3 07 ce ab fc e0 b1 df
d5 cd 95 08 09 6d 5b 2b 8b 6d f5 d6 71 ef 63 77
c0 92 1c b2 3c 27 0a 70 e2 59 8e 6f f8 9d 19 f1
05 ac c2 d3 f0 cb 35 f2 92 80 e1 38 6b 6f 64 c4
ef 22 e1 e1 f2 0d 0c e8 cf fb 22 49 bd 9a 21 37''',
'e':'''01 00 01''',
'd':'''33 a5 04 2a 90 b2 7d 4f 54 51 ca 9b bb d0 b4 47
71 a1 01 af 88 43 40 ae f9 88 5f 2a 4b be 92 e8
94 a7 24 ac 3c 56 8c 8f 97 85 3a d0 7c 02 66 c8
c6 a3 ca 09 29 f1 e8 f1 12 31 88 44 29 fc 4d 9a
e5 5f ee 89 6a 10 ce 70 7c 3e d7 e7 34 e4 47 27
a3 95 74 50 1a 53 26 83 10 9c 2a ba ca ba 28 3c
31 b4 bd 2f 53 c3 ee 37 e3 52 ce e3 4f 9e 50 3b
d8 0c 06 22 ad 79 c6 dc ee 88 35 47 c6 a3 b3 25'''
},
# Message
'''85 13 84 cd fe 81 9c 22 ed 6c 4c cb 30 da eb 5c
f0 59 bc 8e 11 66 b7 e3 53 0c 4c 23 3e 2b 5f 8f
71 a1 cc a5 82 d4 3e cc 72 b1 bc a1 6d fc 70 13
22 6b 9e''',
# Signature
'''3e f7 f4 6e 83 1b f9 2b 32 27 41 42 a5 85 ff ce
fb dc a7 b3 2a e9 0d 10 fb 0f 0c 72 99 84 f0 4e
f2 9a 9d f0 78 07 75 ce 43 73 9b 97 83 83 90 db
0a 55 05 e6 3d e9 27 02 8d 9d 29 b2 19 ca 2c 45
17 83 25 58 a5 5d 69 4a 6d 25 b9 da b6 60 03 c4
cc cd 90 78 02 19 3b e5 17 0d 26 14 7d 37 b9 35
90 24 1b e5 1c 25 05 5f 47 ef 62 75 2c fb e2 14
18 fa fe 98 c2 2c 4d 4d 47 72 4f db 56 69 e8 43''',
# Salt
'''ef 28 69 fa 40 c3 46 cb 18 3d ab 3d 7b ff c9 8f
d5 6d f4 2d''',
# Hash
SHA
),
#
# Example 2.1 to be found in
# ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip
#
(
# Private key
{
'n':'''01 d4 0c 1b cf 97 a6 8a e7 cd bd 8a 7b f3 e3 4f
a1 9d cc a4 ef 75 a4 74 54 37 5f 94 51 4d 88 fe
d0 06 fb 82 9f 84 19 ff 87 d6 31 5d a6 8a 1f f3
a0 93 8e 9a bb 34 64 01 1c 30 3a d9 91 99 cf 0c
7c 7a 8b 47 7d ce 82 9e 88 44 f6 25 b1 15 e5 e9
c4 a5 9c f8 f8 11 3b 68 34 33 6a 2f d2 68 9b 47
2c bb 5e 5c ab e6 74 35 0c 59 b6 c1 7e 17 68 74
fb 42 f8 fc 3d 17 6a 01 7e dc 61 fd 32 6c 4b 33
c9''',
'e':'''01 00 01''',
'd':'''02 7d 14 7e 46 73 05 73 77 fd 1e a2 01 56 57 72
17 6a 7d c3 83 58 d3 76 04 56 85 a2 e7 87 c2 3c
15 57 6b c1 6b 9f 44 44 02 d6 bf c5 d9 8a 3e 88
ea 13 ef 67 c3 53 ec a0 c0 dd ba 92 55 bd 7b 8b
b5 0a 64 4a fd fd 1d d5 16 95 b2 52 d2 2e 73 18
d1 b6 68 7a 1c 10 ff 75 54 5f 3d b0 fe 60 2d 5f
2b 7f 29 4e 36 01 ea b7 b9 d1 ce cd 76 7f 64 69
2e 3e 53 6c a2 84 6c b0 c2 dd 48 6a 39 fa 75 b1'''
},
# Message
'''da ba 03 20 66 26 3f ae db 65 98 48 11 52 78 a5
2c 44 fa a3 a7 6f 37 51 5e d3 36 32 10 72 c4 0a
9d 9b 53 bc 05 01 40 78 ad f5 20 87 51 46 aa e7
0f f0 60 22 6d cb 7b 1f 1f c2 7e 93 60''',
# Signature
'''01 4c 5b a5 33 83 28 cc c6 e7 a9 0b f1 c0 ab 3f
d6 06 ff 47 96 d3 c1 2e 4b 63 9e d9 13 6a 5f ec
6c 16 d8 88 4b dd 99 cf dc 52 14 56 b0 74 2b 73
68 68 cf 90 de 09 9a db 8d 5f fd 1d ef f3 9b a4
00 7a b7 46 ce fd b2 2d 7d f0 e2 25 f5 46 27 dc
65 46 61 31 72 1b 90 af 44 53 63 a8 35 8b 9f 60
76 42 f7 8f ab 0a b0 f4 3b 71 68 d6 4b ae 70 d8
82 78 48 d8 ef 1e 42 1c 57 54 dd f4 2c 25 89 b5
b3''',
# Salt
'''57 bf 16 0b cb 02 bb 1d c7 28 0c f0 45 85 30 b7
d2 83 2f f7''',
SHA
),
#
# Example 8.1 to be found in
# ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip
#
(
# Private key
{
'n':'''49 53 70 a1 fb 18 54 3c 16 d3 63 1e 31 63 25 5d
f6 2b e6 ee e8 90 d5 f2 55 09 e4 f7 78 a8 ea 6f
bb bc df 85 df f6 4e 0d 97 20 03 ab 36 81 fb ba
6d d4 1f d5 41 82 9b 2e 58 2d e9 f2 a4 a4 e0 a2
d0 90 0b ef 47 53 db 3c ee 0e e0 6c 7d fa e8 b1
d5 3b 59 53 21 8f 9c ce ea 69 5b 08 66 8e de aa
dc ed 94 63 b1 d7 90 d5 eb f2 7e 91 15 b4 6c ad
4d 9a 2b 8e fa b0 56 1b 08 10 34 47 39 ad a0 73
3f''',
'e':'''01 00 01''',
'd':'''6c 66 ff e9 89 80 c3 8f cd ea b5 15 98 98 83 61
65 f4 b4 b8 17 c4 f6 a8 d4 86 ee 4e a9 13 0f e9
b9 09 2b d1 36 d1 84 f9 5f 50 4a 60 7e ac 56 58
46 d2 fd d6 59 7a 89 67 c7 39 6e f9 5a 6e ee bb
45 78 a6 43 96 6d ca 4d 8e e3 de 84 2d e6 32 79
c6 18 15 9c 1a b5 4a 89 43 7b 6a 61 20 e4 93 0a
fb 52 a4 ba 6c ed 8a 49 47 ac 64 b3 0a 34 97 cb
e7 01 c2 d6 26 6d 51 72 19 ad 0e c6 d3 47 db e9'''
},
# Message
'''81 33 2f 4b e6 29 48 41 5e a1 d8 99 79 2e ea cf
6c 6e 1d b1 da 8b e1 3b 5c ea 41 db 2f ed 46 70
92 e1 ff 39 89 14 c7 14 25 97 75 f5 95 f8 54 7f
73 56 92 a5 75 e6 92 3a f7 8f 22 c6 99 7d db 90
fb 6f 72 d7 bb 0d d5 74 4a 31 de cd 3d c3 68 58
49 83 6e d3 4a ec 59 63 04 ad 11 84 3c 4f 88 48
9f 20 97 35 f5 fb 7f da f7 ce c8 ad dc 58 18 16
8f 88 0a cb f4 90 d5 10 05 b7 a8 e8 4e 43 e5 42
87 97 75 71 dd 99 ee a4 b1 61 eb 2d f1 f5 10 8f
12 a4 14 2a 83 32 2e db 05 a7 54 87 a3 43 5c 9a
78 ce 53 ed 93 bc 55 08 57 d7 a9 fb''',
# Signature
'''02 62 ac 25 4b fa 77 f3 c1 ac a2 2c 51 79 f8 f0
40 42 2b 3c 5b af d4 0a 8f 21 cf 0f a5 a6 67 cc
d5 99 3d 42 db af b4 09 c5 20 e2 5f ce 2b 1e e1
e7 16 57 7f 1e fa 17 f3 da 28 05 2f 40 f0 41 9b
23 10 6d 78 45 aa f0 11 25 b6 98 e7 a4 df e9 2d
39 67 bb 00 c4 d0 d3 5b a3 55 2a b9 a8 b3 ee f0
7c 7f ec db c5 42 4a c4 db 1e 20 cb 37 d0 b2 74
47 69 94 0e a9 07 e1 7f bb ca 67 3b 20 52 23 80
c5''',
# Salt
'''1d 65 49 1d 79 c8 64 b3 73 00 9b e6 f6 f2 46 7b
ac 4c 78 fa''',
SHA
)
)
def testSign1(self):
for i in range(len(self._testData)):
# Build the key
comps = [ long(rws(self._testData[i][0][x]),16) for x in ('n','e','d') ]
key = MyKey(RSA.construct(comps))
# Hash function
h = self._testData[i][4].new()
# Data to sign
h.update(t2b(self._testData[i][1]))
# Salt
test_salt = t2b(self._testData[i][3])
key._randfunc = lambda N: test_salt
# The real test
signer = PKCS.new(key)
self.failUnless(signer.can_sign())
s = signer.sign(h)
self.assertEqual(s, t2b(self._testData[i][2]))
def testVerify1(self):
for i in range(len(self._testData)):
# Build the key
comps = [ long(rws(self._testData[i][0][x]),16) for x in ('n','e') ]
key = MyKey(RSA.construct(comps))
# Hash function
h = self._testData[i][4].new()
# Data to sign
h.update(t2b(self._testData[i][1]))
# Salt
test_salt = t2b(self._testData[i][3])
# The real test
key._randfunc = lambda N: test_salt
verifier = PKCS.new(key)
self.failIf(verifier.can_sign())
result = verifier.verify(h, t2b(self._testData[i][2]))
self.failUnless(result)
def testSignVerify(self):
h = SHA.new()
h.update(b('blah blah blah'))
rng = Random.new().read
key = MyKey(RSA.generate(1024,rng))
# Helper function to monitor what's request from MGF
global mgfcalls
def newMGF(seed,maskLen):
global mgfcalls
mgfcalls += 1
return bchr(0x00)*maskLen
# Verify that PSS is friendly to all ciphers
for hashmod in (MD2,MD5,SHA,SHA224,SHA256,SHA384,RIPEMD):
h = hashmod.new()
h.update(b('blah blah blah'))
# Verify that sign() asks for as many random bytes
# as the hash output size
key.asked = 0
signer = PKCS.new(key)
s = signer.sign(h)
self.failUnless(signer.verify(h, s))
self.assertEqual(key.asked, h.digest_size)
h = SHA.new()
h.update(b('blah blah blah'))
# Verify that sign() uses a different salt length
for sLen in (0,3,21):
key.asked = 0
signer = PKCS.new(key, saltLen=sLen)
s = signer.sign(h)
self.assertEqual(key.asked, sLen)
self.failUnless(signer.verify(h, s))
# Verify that sign() uses the custom MGF
mgfcalls = 0
signer = PKCS.new(key, newMGF)
s = signer.sign(h)
self.assertEqual(mgfcalls, 1)
self.failUnless(signer.verify(h, s))
# Verify that sign() does not call the RNG
# when salt length is 0, even when a new MGF is provided
key.asked = 0
mgfcalls = 0
signer = PKCS.new(key, newMGF, 0)
s = signer.sign(h)
self.assertEqual(key.asked,0)
self.assertEqual(mgfcalls, 1)
self.failUnless(signer.verify(h, s))
class testSign1_mytest():
# List of tuples with test data for PKCS#1 PSS
# Each tuple is made up by:
# Item #0: dictionary with RSA key component, or key to import
# Item #1: data to hash and sign
# Item #2: signature of the data #1, done with the key #0,
# and salt #3 after hashing it with #4
# Item #3: salt
# Item #4: hash object generator
def __init__(self, rsa_parse, msg):
_testData = (
#
# From in pss-vect.txt to be found in
# ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip
#
(
# Private key
{
'n':'''a2 ba 40 ee 07 e3 b2 bd 2f 02 ce 22 7f 36 a1 95
02 44 86 e4 9c 19 cb 41 bb bd fb ba 98 b2 2b 0e
57 7c 2e ea ff a2 0d 88 3a 76 e6 5e 39 4c 69 d4
b3 c0 5a 1e 8f ad da 27 ed b2 a4 2b c0 00 fe 88
8b 9b 32 c2 2d 15 ad d0 cd 76 b3 e7 93 6e 19 95
5b 22 0d d1 7d 4e a9 04 b1 ec 10 2b 2e 4d e7 75
12 22 aa 99 15 10 24 c7 cb 41 cc 5e a2 1d 00 ee
b4 1f 7c 80 08 34 d2 c6 e0 6b ce 3b ce 7e a9 a5''',
'e':'''01 00 01''',
# In the test vector, only p and q were given...
# d is computed offline as e^{-1} mod (p-1)(q-1)
'd':'''50e2c3e38d886110288dfc68a9533e7e12e27d2aa56
d2cdb3fb6efa990bcff29e1d2987fb711962860e7391b1ce01
ebadb9e812d2fbdfaf25df4ae26110a6d7a26f0b810f54875e
17dd5c9fb6d641761245b81e79f8c88f0e55a6dcd5f133abd3
5f8f4ec80adf1bf86277a582894cb6ebcd2162f1c7534f1f49
47b129151b71'''
},
# Data to sign
'''85 9e ef 2f d7 8a ca 00 30 8b dc 47 11 93 bf 55
bf 9d 78 db 8f 8a 67 2b 48 46 34 f3 c9 c2 6e 64
78 ae 10 26 0f e0 dd 8c 08 2e 53 a5 29 3a f2 17
3c d5 0c 6d 5d 35 4f eb f7 8b 26 02 1c 25 c0 27
12 e7 8c d4 69 4c 9f 46 97 77 e4 51 e7 f8 e9 e0
4c d3 73 9c 6b bf ed ae 48 7f b5 56 44 e9 ca 74
ff 77 a5 3c b7 29 80 2f 6e d4 a5 ff a8 ba 15 98
90 fc''',
# Signature
'''8d aa 62 7d 3d e7 59 5d 63 05 6c 7e c6 59 e5 44
06 f1 06 10 12 8b aa e8 21 c8 b2 a0 f3 93 6d 54
dc 3b dc e4 66 89 f6 b7 95 1b b1 8e 84 05 42 76
97 18 d5 71 5d 21 0d 85 ef bb 59 61 92 03 2c 42
be 4c 29 97 2c 85 62 75 eb 6d 5a 45 f0 5f 51 87
6f c6 74 3d ed dd 28 ca ec 9b b3 0e a9 9e 02 c3
48 82 69 60 4f e4 97 f7 4c cd 7c 7f ca 16 71 89
71 23 cb d3 0d ef 5d 54 a2 b5 53 6a d9 0a 74 7e''',
# Salt
'''e3 b5 d5 d0 02 c1 bc e5 0c 2b 65 ef 88 a1 88 d8
3b ce 7e 61''',
# Hash algorithm
SHA
),
#
# Example 1.1 to be found in
# ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip
#
(
# Private key
{
'n':'''a5 6e 4a 0e 70 10 17 58 9a 51 87 dc 7e a8 41 d1
56 f2 ec 0e 36 ad 52 a4 4d fe b1 e6 1f 7a d9 91
d8 c5 10 56 ff ed b1 62 b4 c0 f2 83 a1 2a 88 a3
94 df f5 26 ab 72 91 cb b3 07 ce ab fc e0 b1 df
d5 cd 95 08 09 6d 5b 2b 8b 6d f5 d6 71 ef 63 77
c0 92 1c b2 3c 27 0a 70 e2 59 8e 6f f8 9d 19 f1
05 ac c2 d3 f0 cb 35 f2 92 80 e1 38 6b 6f 64 c4
ef 22 e1 e1 f2 0d 0c e8 cf fb 22 49 bd 9a 21 37''',
'e':'''01 00 01''',
'd':'''33 a5 04 2a 90 b2 7d 4f 54 51 ca 9b bb d0 b4 47
71 a1 01 af 88 43 40 ae f9 88 5f 2a 4b be 92 e8
94 a7 24 ac 3c 56 8c 8f 97 85 3a d0 7c 02 66 c8
c6 a3 ca 09 29 f1 e8 f1 12 31 88 44 29 fc 4d 9a
e5 5f ee 89 6a 10 ce 70 7c 3e d7 e7 34 e4 47 27
a3 95 74 50 1a 53 26 83 10 9c 2a ba ca ba 28 3c
31 b4 bd 2f 53 c3 ee 37 e3 52 ce e3 4f 9e 50 3b
d8 0c 06 22 ad 79 c6 dc ee 88 35 47 c6 a3 b3 25'''
},
# Message
'''cd c8 7d a2 23 d7 86 df 3b 45 e0 bb bc 72 13 26
d1 ee 2a f8 06 cc 31 54 75 cc 6f 0d 9c 66 e1 b6
23 71 d4 5c e2 39 2e 1a c9 28 44 c3 10 10 2f 15
6a 0d 8d 52 c1 f4 c4 0b a3 aa 65 09 57 86 cb 76
97 57 a6 56 3b a9 58 fe d0 bc c9 84 e8 b5 17 a3
d5 f5 15 b2 3b 8a 41 e7 4a a8 67 69 3f 90 df b0
61 a6 e8 6d fa ae e6 44 72 c0 0e 5f 20 94 57 29
cb eb e7 7f 06 ce 78 e0 8f 40 98 fb a4 1f 9d 61
93 c0 31 7e 8b 60 d4 b6 08 4a cb 42 d2 9e 38 08
a3 bc 37 2d 85 e3 31 17 0f cb f7 cc 72 d0 b7 1c
29 66 48 b3 a4 d1 0f 41 62 95 d0 80 7a a6 25 ca
b2 74 4f d9 ea 8f d2 23 c4 25 37 02 98 28 bd 16
be 02 54 6f 13 0f d2 e3 3b 93 6d 26 76 e0 8a ed
1b 73 31 8b 75 0a 01 67 d0''',
# Signature
'''90 74 30 8f b5 98 e9 70 1b 22 94 38 8e 52 f9 71
fa ac 2b 60 a5 14 5a f1 85 df 52 87 b5 ed 28 87
e5 7c e7 fd 44 dc 86 34 e4 07 c8 e0 e4 36 0b c2
26 f3 ec 22 7f 9d 9e 54 63 8e 8d 31 f5 05 12 15
df 6e bb 9c 2f 95 79 aa 77 59 8a 38 f9 14 b5 b9
c1 bd 83 c4 e2 f9 f3 82 a0 d0 aa 35 42 ff ee 65
98 4a 60 1b c6 9e b2 8d eb 27 dc a1 2c 82 c2 d4
c3 f6 6c d5 00 f1 ff 2b 99 4d 8a 4e 30 cb b3 3c''',
# Salt
'''de e9 59 c7 e0 64 11 36 14 20 ff 80 18 5e d5 7f
3e 67 76 af''',
# Hash
SHA
),
(
# Private key
"""-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQC1OZn2ExXQ5z/1XhBomiy7j6YGQU7EuBXcvnvizU6fGkdcLWKA
MBQJxHOnCJwUSvCecea58P4WSDaAGk/Rbd3y1b1Akr7ilcpW+l0ymfF95pBIMBt1
gXDaHtaM1GgR4H0FisR68fHm2LDMNdGdVdGz3vqpUBboVx7fmLyEAxswuQIDAQAB
AoGBAKkGWW/mqxFVrhSnL/yv14r0VvA8lz/pRhLF4vxNasgAFZCGj/lpXjch8JBY
+mH+51+Qcpb4i7OylIp0f/+gTkGuSAYPYwzwqG3ALwAF4Z5i8qKmklQtEJ+9p7lu
POivMzla4Qx7bvBp+Bq4/8lyg5o+D279MN68455wub516+7RAkEAz+InzJO8H8lN
OKpysNCPx9WQNkpMLODRlOYxDg6/QiHNBshT+Kd8tU9xT8fqPWCybfrYNKDWEahz
C/QVPWR5JQJBAN8r1qZo0KWvOay81ogC6aLoLauJX6UHuhxN1U1cS/AjdSJezWZp
L3zmS9iSJbTyojzwGTly6e+2kGHYafLwlwUCQGD+Ujd/jrz9/Yu863pYNV215W2P
SO9/jgn9RVIby10dzD2n5pYT/3nRMTtaOY6duWLbMVmM2ZSvlc4z+l0ErgkCQA8F
SVY7+ccdCxm4QAw5ffYsAF7qSRi3c2xSRMgHLUlFaa3diZ+Z9stGSNaTx5vtNMQ7
OMdoF5y9wewD/+WNEe0CQQCPXCxOab5++0AB25wqwP2Zk/nFiNznd7+Rk/TIS4c+
+C8/NPfkYJD7aNcpflFvyeLAWJgtSs+ebVHYpEZpUnY5
-----END RSA PRIVATE KEY-----""",
# Data to sign
"abc",
# Signature
'''7e a9 02 59 20 eb a1 b1 67 99 56 44 72 88 00 3d
11 4a 3d 16 40 d2 77 6b 60 62 06 b6 19 f0 7e de
52 93 0d d9 74 25 44 fd b3 4f 5c cf fb b7 98 34
ae ad e3 9e 79 93 fc 5f 4b 48 d0 08 95 c4 66 5e
d5 17 7a 5b 05 a2 7e fb 21 72 68 12 f7 6d 3b fe
97 30 81 c5 75 de e4 26 6c d6 d8 28 0b ae 33 a0
f6 9d f0 23 2f f7 12 0b 40 a3 37 7d 25 bf 60 c9
84 d4 19 27 61 27 f6 a0 62 8b 52 32 26 9a 0c 77''',
# Salt
'''25 5a 3c e4 34 ae e1 41 09 a5 96 f6 a6 7e 34 b6
8e 56 3f 2d 92 07 41 55 f3 e4 a5 9e 47 98 d2 e4''',
# Hash algorithm
SHA256
),
(
# Private key
"""-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----""",
# Data to sign
"abc",
# Signature
'''70 1b 61 7e 96 cf b5 9e 59 af ed eb c2 b3 55 fd
64 c2 6c b4 c7 ad 62 19 af ed f3 b0 82 fa 1d e7
8f 6f 01 a1 74 67 48 9b a6 c0 ba 7f dc ce 91 49
7c da d3 d0 aa c8 e9 4d be 9f ea 1f 62 0e 11 55
4e 82 03 c3 fb 4a f4 ba d9 ab 08 e4 8f 07 ba f0
ed 5d 6e f7 8b 27 9d 08 dd b4 36 b5 3b 89 b2 e0
f3 43 b2 9b 4a e6 b1 03 b4 87 5d a9 58 3c 2b 6f
fa 22 0c 28 d9 28 7a b6 c4 7f 03 f0 21 55 d0 be
12 0a 8a e9 c5 3c e5 d2 6b e3 9a ce 92 87 e4 10
5f e0 66 db 46 66 e5 72 be b4 3c d1 8e cf 1a ea
ba 69 65 09 e9 a1 04 55 3c b5 92 87 57 97 00 cf
47 20 e8 8a df 93 18 6a cf 2b d3 af 55 8f 55 d5
78 a0 fa 27 e8 f5 f5 a6 3b b5 ec f1 c2 8d b5 f9
68 de ca b4 e2 4a 00 cd f5 19 47 8e 36 f4 0e 4f
5d 34 a3 ec 63 39 08 15 69 b2 83 6d f7 b0 99 3b
b0 bf 2b e6 ae 9a 60 5b 43 e4 18 18 ec be 09 ba
85 8a dc 77 75 cd c6 eb 98 d6 b0 9c de a4 d7 1a
df 2c 3f aa 7c 52 ff 3e 0f 87 20 2b dd 93 92 49
43 f8 b9 d4 8e de c5 3b 37 a5 ee 8c 68 cc 6d ff
c6 98 c6 af 00 b8 f4 bf b7 7f 51 b0 53 a5 68 fb
bf b2 62 57 2e cd 7c c0 0e cc 3e 69 3b a5 a2 bf
3f ad c6 1b 66 39 57 71 e3 b7 c8 20 b6 51 46 58
70 be 64 96 38 c4 e1 51 3b 63 68 3c 38 fb d4 b2
60 ed 0f 2e b5 cf 1e 2c 9c ec 7f b9 19 51 3b 4c
30 0d 74 a0 e6 f6 14 ea ff cd c5 2e 6a cd c2 f5
53 3b f4 64 1a 44 9e 16 64 d6 82 f5 7d 1a 47 00
51 04 90 1b 8e b7 91 d6 73 91 46 74 bd ea 08 86
41 e4 f5 e5 04 61 f8 bd a4 b7 56 6a 0b a2 b3 ee
00 f8 cc 04 28 36 de 99 05 2b e2 eb 92 ff 26 1d
db 29 5a 72 51 a4 b7 f7 ea 5c 27 53 68 0d 89 8c
1f 17 87 85 9c 1d 8d 42 b4 cb 42 49 c7 0c 1e df
e0 8e ee e3 1e 77 5d 16 5f 75 31 1c 5c af 3e 02
''',
# Salt
'''c8 e6 96 a2 a5 5b ab 2f eb b8 42 89 f8 de 0c 8d
8d 82 99 b8 25 b8 f2 35 73 2c 49 d4 d1 f3 04 4d''',
# Hash algorithm
SHA256
),
)
self._testData = _testData
self.rsa_parse = rsa_parse
self.msg = msg
def sign1_mytest(self):
for i in range(len(self._testData)):
print("Test vector[%d]" %i)
# Build the key
if isStr(self._testData[i][0]):
print("pem")
key = RSA.importKey(self._testData[i][0])
else:
comps = [ long(rws(self._testData[i][0][x]),16) for x in ('n','e','d') ]
key = MyKey(RSA.construct(comps))
# Hash function
h = self._testData[i][4].new()
# Data to sign
try:
print("try")
h.update(t2b(self._testData[i][1]))
except:
print("except")
h.update(b(self._testData[i][1]))
# Salt
test_salt = t2b(self._testData[i][3])
key._randfunc = lambda N: test_salt
# The real test
signer = PKCS.new(key)
t_flag = signer.can_sign()
if t_flag:
print("mytest: can sign")
else:
print("mytest: can't sign")
s = signer.sign(h)
print("salt:")
#rsa_dump(test_salt)
rsa_dump(key._randfunc(test_salt))
print("signature:")
rsa_dump(s)
if s == t2b(self._testData[i][2]):
print("[Pass] RSA PSS signature compare pass")
else:
print("[Fail] PSA PSS signature compare fail")
def sbc_rsa_sign1_json(self):
row = self.rsa_parse
# Build the key
if isStr(row[0]):
print("pem")
key = RSA.importKey(row[0])
else:
comps = [ long(rws(row[0][x]),16) for x in ('n','e','d') ]
key = MyKey(RSA.construct(comps))
# Hash function
if(row[4] == "SHA"):
h = SHA.new()
elif(row[4] == "SHA256"):
h = SHA256.new()
elif(row[4] == "SHA384"):
h = SHA384.new()
elif(row[4] == "SHA512"):
h = SHA512.new()
else:
h = SHA256.new()
# Data to sign
if(row[5] == 1):
try:
print("try")
h.update(t2b(row[1]))
except:
print("except")
h.update(b(row[1]))
else:
h.update(self.msg)
rsa_dump(h.digest())
# Salt
test_salt = t2b(row[3])
key._randfunc = lambda N: test_salt
# The real test
signer = PKCS.new(key)
t_flag = signer.can_sign()
if t_flag:
print("mytest: can sign")
else:
print("mytest: can't sign")
s = signer.sign(h)
print("salt:")
#rsa_dump(test_salt)
rsa_dump(key._randfunc(test_salt))
print("signature:")
rsa_dump(s)
if s == t2b(row[2]):
print("[Pass] RSA PSS signature compare pass")
else:
print("[Fail] PSA PSS signature compare fail")
return s
def verify1_mytest(self):
for i in range(len(self._testData)):
print("Test vector[%d]" %i)
row = self._testData[i]
# Build the key
if isStr(row[0]):
key = RSA.importKey(row[0]).publickey()
else:
comps = [ long(rws(self._testData[i][0][x]),16) for x in ('n','e') ]
key = MyKey(RSA.construct(comps))
# Hash function
h = self._testData[i][4].new()
# Data to sign
try:
h.update(t2b(self._testData[i][1]))
# Salt
test_salt = t2b(self._testData[i][3])
except:
h.update(b(self._testData[i][1]))
# Salt
test_salt = b(self._testData[i][3])
# The real test
key._randfunc = lambda N: test_salt
verifier = PKCS.new(key)
t_flag = verifier.can_sign()
if t_flag:
print("mytest: can't verify")
else:
print("mytest: can verify")
result = verifier.verify(h, t2b(self._testData[i][2]))
if result:
print("[Pass] RSA PSS verify pass")
else:
print("[Fail] RSA PSS verify fail")
def get_tests(config={}):
tests = []
tests += list_test_cases(PKCS1_PSS_Tests)
return tests
if __name__ == '__main__':
suite = lambda: unittest.TestSuite(get_tests())
unittest.main(defaultTest='suite')
# vim:set ts=4 sw=4 sts=4