Class: Milenage::Kernel
- Inherits:
-
Object
- Object
- Milenage::Kernel
- Defined in:
- lib/milenage.rb
Overview
The core class for calculating Milenage security functions.
To use this class, determine the operator variant algorithm configuration field (OP) or the pre-encrypted version of the same (OPc) and also determine the user-specific key value (KEY). Create an instance of the kernel class, passing the key, then set the OP/OPc as needed:
m = Milenage::Kernel.new(KEY)
m.op = OP # or m.opc = OPc
At this point, the kernel instance can be used to calculate security functions for the user:
mac_a = m.f1(RAND, SQN, AMF)
mac_s = m.f1_star(RAND, SQN, AMF)
res = m.f2(RAND)
ck = m.f3(RAND)
ik = m.f4(RAND)
ak = m.r5(RAND) # or ak = m.f5_star(RAND)
You may change the OP/OPc at any time if needed:
m.op = NEW_OP
m.opc = NEW_OPc
Instance Method Summary collapse
-
#f1(rand, sqn, amf) ⇒ Object
Calculate the network authentication code (MAC-A).
-
#f1_star(rand, sqn, amf) ⇒ Object
Calculate the resync authentication code (MAC-S).
-
#f2(rand) ⇒ Object
Calculate the response (RES).
-
#f3(rand) ⇒ Object
Calculate the confidentiallity key (CK).
-
#f4(rand) ⇒ Object
Calculate the integrity key (IK).
-
#f5(rand) ⇒ Object
Calculate the anonymity key (AK).
-
#f5_star(rand) ⇒ Object
Calculate the anonymity resynch key (AK).
-
#initialize(key) ⇒ Kernel
constructor
Create a single user’s kernel instance, remember to set OP or OPc before attempting to use the security functions.
-
#op=(op) ⇒ Object
Set the Operator Variant Algorithm Configuration field.
-
#opc ⇒ Object
Standard getter for the OPc.
-
#opc=(opc) ⇒ Object
Set the precomputed encoded Operator Variant Algorithm Configuration field.
Constructor Details
#initialize(key) ⇒ Kernel
Create a single user’s kernel instance, remember to set OP or OPc before attempting to use the security functions.
To change the algorithm variables as described in TS 35.206 subclass this Kernel class and modify ‘@c`, `@r` or `@kernel` after calling super. E.G.
class MyKernel < Kernel
def initialize(key)
super
@r = [10, 20, 30, 40, 50]
end
end
When doing this, ‘@kernel` should be set to a 128-bit MAC function with the same API as `OpenSSL::Cipher`, if this is not the case, you may need to overload #enc as well to match the API.
47 48 49 50 51 52 53 |
# File 'lib/milenage.rb', line 47 def initialize(key) fail "KEY must be 128 bits" unless key.each_byte.to_a.length == 16 @key = key @c = [0, 1, 2, 4, 8].map { |i| [0, i].pack("Q>2") } @r = [64, 0, 32, 64, 96] @kernel = OpenSSL::Cipher::AES128.new(:ECB) end |
Instance Method Details
#f1(rand, sqn, amf) ⇒ Object
Calculate the network authentication code (MAC-A)
82 83 84 |
# File 'lib/milenage.rb', line 82 def f1(rand, sqn, amf) step_a(rand, sqn, amf)[0..7] end |
#f1_star(rand, sqn, amf) ⇒ Object
Calculate the resync authentication code (MAC-S)
87 88 89 |
# File 'lib/milenage.rb', line 87 def f1_star(rand, sqn, amf) step_a(rand, sqn, amf)[8..15] end |
#f2(rand) ⇒ Object
Calculate the response (RES)
92 93 94 |
# File 'lib/milenage.rb', line 92 def f2(rand) step_b(rand)[8..15] end |
#f3(rand) ⇒ Object
Calculate the confidentiallity key (CK)
97 98 99 |
# File 'lib/milenage.rb', line 97 def f3(rand) step_c(rand) end |
#f4(rand) ⇒ Object
Calculate the integrity key (IK)
102 103 104 |
# File 'lib/milenage.rb', line 102 def f4(rand) step_d(rand) end |
#f5(rand) ⇒ Object
Calculate the anonymity key (AK)
107 108 109 |
# File 'lib/milenage.rb', line 107 def f5(rand) step_b(rand)[0..5] end |
#f5_star(rand) ⇒ Object
Calculate the anonymity resynch key (AK)
112 113 114 |
# File 'lib/milenage.rb', line 112 def f5_star(rand) step_e(rand)[0..5] end |
#op=(op) ⇒ Object
Set the Operator Variant Algorithm Configuration field.
Either this or #opc= must be called before any of the security functions are evaluated.
59 60 61 62 |
# File 'lib/milenage.rb', line 59 def op=(op) fail "OP must be 128 bits" unless op.each_byte.to_a.length == 16 @opc = xor(enc(op), op) end |
#opc ⇒ Object
Standard getter for the OPc.
76 77 78 79 |
# File 'lib/milenage.rb', line 76 def opc fail "Must set OP or OPc before retrieving OPc" unless @opc @opc end |
#opc=(opc) ⇒ Object
Set the precomputed encoded Operator Variant Algorithm Configuration field. Note that there are no checks that this value is even feasible for the given key.
Either this or #op= must be called before any of the security functions are evaluated.
70 71 72 73 |
# File 'lib/milenage.rb', line 70 def opc=(opc) fail "OPc must be 128 bits" unless opc.each_byte.to_a.length == 16 @opc = opc end |