Class: CMAC::Digest

Inherits:
Object
  • Object
show all
Defined in:
ext/cmac/wrapper.c

Instance Method Summary collapse

Constructor Details

#initialize(key) ⇒ Object

Initialize an CMAC::Digest object with a key. Performs basic length validation on the key.



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'ext/cmac/wrapper.c', line 12

static VALUE cmac_rb_initialize(VALUE self, VALUE key) {
 
  int keyLen;
  
  // Replace key value with key.to_str
  StringValue(key);
  
  // Get the key length as an int.
  keyLen = RSTRING_LEN(key);
  
  // Make sure key is not empty
  if (keyLen == 0) {
    rb_raise(rb_eArgError, "Key must be non-empty.");
  }
  
  // Make sure key is acceptable size
  if (keyLen != AES_BLOCK_SIZE) {
    rb_raise(rb_eArgError, "Only 128-bit keys are supported.");
  }
  
  // Set key as instance variable
  rb_iv_set(self, "@key", key);
  
  return self;
  
}

Instance Method Details

#update(plaintext) ⇒ Object

Compute the digest of some plaintext



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'ext/cmac/wrapper.c', line 70

static VALUE cmac_rb_update(VALUE self, VALUE plaintext) {
  
  // Holds the CMAC context object.
  cmac_ctx ctx;
  
  // Input plaintext as byte array.
  const unsigned char* cPlaintext;
  
  // Length of the input plaintext.
  int cPlaintextLen;
  
  // Holds the CMAC ciphertext object.
  unsigned char* cDigest;
  
  // Holds the length of the CMAC digest.
  int cDigestLen;
  
  // Get the CMAC context based on the instance's key.
  if (!cmac_rb_get_ctx(self, &ctx)) {
    rb_raise(rb_eRuntimeError, "Could not get CMAC context");
  }
  
  // Replace the plaintext with plaintext.to_str
  StringValue(plaintext);
  
  // Convert the plaintext to a byte array.
  cPlaintext = (const unsigned char*) RSTRING_PTR(plaintext);
  cPlaintextLen = RSTRING_LEN(plaintext);
  
  // Allocate space for the ciphertext.
  cDigestLen = sizeof(unsigned char) * AES_BLOCK_SIZE;
  cDigest = (unsigned char*) malloc(cDigestLen);
  
  // Call aes_cmac with all parameters.
  cmac_encrypt(&ctx, cPlaintext, cPlaintextLen, cDigest);
  
  // Return a new Ruby string with the resulting value.
  return rb_str_new((const char*) cDigest, cDigestLen);
  
}