Ignore:
Timestamp:
02/09/09 13:31:09 (12 years ago)
Author:
Alaric Snell-Pym
Message:

V1.1: cbc* mode

File:
1 edited

Legend:

Unmodified
Added
Removed
  • release/3/crypto-tools/trunk/crypto-tools.scm

    r13197 r13221  
    44(declare (export
    55   blob->hexstring blob->hexstring/uppercase hexstring->blob
    6    subblob blob-xor blob-pad blob-unpad
    7    make-cbc-encryptor make-cbc-decryptor))
     6   blob-xor blob-pad blob-unpad
     7   make-cbc-encryptor make-cbc-decryptor
     8   make-cbc*-encryptor make-cbc*-decryptor))
    89
    910(define *the-null-blob* (make-blob 0))
     
    190191                      (output (make-blob inputsize)))
    191192                  (decrypt input 0 inputsize iv output 0)))))
     193
     194; As above, but the encryptor stores the IV in the output block (encrypted)...
     195
     196(define (make-cbc*-encryptor encryptor blocksize)
     197   (letrec ((encrypt (lambda (input inoffset inputsize iv output outoffset)
     198         (cond
     199            ((= inoffset inputsize) ; Zero bytes
     200               (let* ((inblock (blob-pad *the-null-blob* blocksize))
     201                      (outblock (encryptor (blob-xor iv inblock))))
     202                  (move-memory! outblock output blocksize 0 outoffset)
     203                  output)) ; Terminate
     204            ((<= (+ inoffset blocksize) inputsize) ; Just another block
     205               (let* ((inblock (subblob input inoffset blocksize))
     206                      (outblock (encryptor (blob-xor iv inblock))))
     207
     208                  (move-memory! outblock output blocksize 0 outoffset)
     209                  (encrypt input (+ inoffset blocksize) inputsize outblock output (+ outoffset blocksize)))) ; Recurse
     210            (else ; Partial block
     211               (let* ((inblock (blob-pad
     212                        (subblob input inoffset (- inputsize inoffset))
     213                        blocksize))
     214                      (outblock (encryptor (blob-xor iv inblock))))
     215
     216                  (move-memory! outblock output blocksize 0 outoffset)
     217                  output)))))) ; Terminate
     218
     219            (lambda (input iv)
     220               (let* ((inputsize (blob-size input))
     221                      (output-whole-blocks (quotient inputsize blocksize))
     222                      (output-overflow (remainder inputsize blocksize))
     223                      (outputsize (if (zero? output-overflow) ; Round up to block size, plus an extra block for the IV
     224                         (+ inputsize blocksize blocksize)
     225                         (* (+ 2 output-whole-blocks) blocksize)))
     226                      (output (make-blob outputsize))
     227                      (encrypted-iv (encryptor iv)))
     228                  (move-memory! encrypted-iv output blocksize)
     229                  (encrypt input 0 inputsize iv output blocksize)))))
     230
     231;... and the decryptor retreives it.
     232
     233(define (make-cbc*-decryptor decryptor blocksize)
     234   (letrec ((decrypt (lambda (input inoffset inputsize iv output outoffset)
     235               (if (= (+ inoffset blocksize) inputsize)
     236                  ; Last block
     237                  (let* ((inblock (subblob input inoffset blocksize))
     238                         (outblock
     239                            (blob-unpad
     240                               (blob-xor iv
     241                                 (decryptor inblock)))))
     242                        (move-memory! outblock output (blob-size outblock) 0 outoffset)
     243                        (subblob output 0 (+ outoffset (blob-size outblock)))) ; Terminate
     244                  ; Not last block
     245                  (let* ((inblock (subblob input inoffset blocksize))
     246                         (outblock
     247                            (blob-xor iv
     248                              (decryptor inblock))))
     249
     250                        (move-memory! outblock output blocksize 0 outoffset)
     251                        (decrypt input (+ inoffset blocksize) inputsize inblock output (+ outoffset blocksize))))))) ; Recurse
     252
     253            (lambda (input)
     254               (let* ((inputsize (blob-size input))
     255                      (output (make-blob inputsize))
     256                      (iv (decryptor (subblob input 0 blocksize))))
     257                  (decrypt input blocksize inputsize iv output 0)))))
Note: See TracChangeset for help on using the changeset viewer.