// Package rocacheck checks if a key was generated by broken Infineon code and // is vulnerable to factorization via the Return of Coppersmith's Attack (ROCA) // / CVE-2017-15361. package rocacheck import ( "crypto/rsa" "math/big" ) type test struct { Prime *big.Int Fingerprints map[int64]struct{} } var tests = make([]test, 17) func init() { bigOne := big.NewInt(1) n := &big.Int{} // relations table from https://github.com/crocs-muni/roca/pull/40 for i, r := range [][2]int64{ {2, 11}, {6, 13}, {8, 17}, {9, 19}, {3, 37}, {26, 53}, {20, 61}, {35, 71}, {24, 73}, {13, 79}, {6, 97}, {51, 103}, {53, 107}, {54, 109}, {42, 127}, {50, 151}, {78, 157}, } { fps := make(map[int64]struct{}) bp := big.NewInt(r[1]) br := big.NewInt(r[0]) for j := int64(0); j < r[1]; j++ { if n.Exp(big.NewInt(j), br, bp).Cmp(bigOne) == 0 { fps[j] = struct{}{} } } tests[i] = test{ Prime: big.NewInt(r[1]), Fingerprints: fps, } } } // IsWeak returns true if a RSA public key is vulnerable to Return of // Coppersmith's Attack (ROCA). func IsWeak(k *rsa.PublicKey) bool { tmp := &big.Int{} for _, t := range tests { if _, ok := t.Fingerprints[tmp.Mod(k.N, t.Prime).Int64()]; !ok { return false } } return true }