+package HMLAN_CRYPT;
+
+use Crypt::Rijndael;
+
+sub decrypt(@)
+{
+ my ($self, $ciphertext) = @_;
+ my $plaintext = '';
+
+ while($ciphertext) {
+ if($self->{'keystream'}) {
+ my $len;
+
+ if (length($self->{'keystream'}) > length($ciphertext)) {
+ $len = length($ciphertext);
+ } else {
+ $len = length($self->{'keystream'});
+ }
+
+ my $cpart = substr($ciphertext, 0, $len);
+ my $kpart = substr($self->{'keystream'}, 0, $len);
+
+ $ciphertext = substr($ciphertext, $len);
+ $self->{'keystream'} = substr($self->{'keystream'}, $len);
+
+ $self->{'ciphertext'} .= $cpart;
+
+ $plaintext .= $cpart ^ $kpart;
+ } else {
+ $self->{'keystream'} = $self->{'cipher'}->encrypt($self->{'ciphertext'});
+ $self->{'ciphertext'}='';
+ }
+ }
+
+ $plaintext;
+}
+
+sub encrypt(@)
+{
+ my ($self, $plaintext) = @_;
+ my $ciphertext = '';
+
+ while($plaintext) {
+ if($self->{'keystream'}) {
+ my $len;
+
+ if (length($self->{'keystream'}) > length($plaintext)) {
+ $len = length($plaintext);
+ } else {
+ $len = length($self->{'keystream'});
+ }
+
+ my $ppart = substr($plaintext, 0, $len);
+ my $kpart = substr($self->{'keystream'}, 0, $len);
+
+ $plaintext = substr($plaintext, $len);
+ $self->{'keystream'} = substr($self->{'keystream'}, $len);
+
+ $self->{'ciphertext'} .= $ppart ^ $kpart;
+
+ $ciphertext .= $ppart ^ $kpart;
+ } else {
+ $self->{'keystream'} = $self->{'cipher'}->encrypt($self->{'ciphertext'});
+ $self->{'ciphertext'}='';
+ }
+ }
+
+ $ciphertext;
+}
+
+sub new
+{
+ my $class = shift;
+ my $key = shift;
+ my $iv = shift;
+
+ my $self = {
+ cipher => Crypt::Rijndael->new($key, Crypt::Rijndael::MODE_ECB()),
+ keystream => '',
+ ciphertext => $iv,
+ };
+
+ bless $self, $class;
+}
+
+1;