#lang racket/base ;; Provide AES CTR mode, since OpenSSL's EVP support for AES CTR mode ;; is still ifdef'd out. ;; ;;; Copyright 2010, 2011, 2012, 2013 Tony Garnock-Jones ;;; ;;; This file is part of marketplace-ssh. ;;; ;;; marketplace-ssh is free software: you can redistribute it and/or ;;; modify it under the terms of the GNU General Public License as ;;; published by the Free Software Foundation, either version 3 of the ;;; License, or (at your option) any later version. ;;; ;;; marketplace-ssh is distributed in the hope that it will be useful, ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;;; General Public License for more details. ;;; ;;; You should have received a copy of the GNU General Public License ;;; along with marketplace-ssh. If not, see ;;; . (provide start-aes-ctr aes-ctr-process!) (require ffi/unsafe) (require ffi/unsafe/define) (require openssl/libcrypto) (define _AES_KEY-pointer _pointer) (define AES_BLOCK_SIZE 16) (define sizeof-AES_KEY 244) ;; TODO: figure out a good way to get this ;; from the header file or the library ;; itself (define-ffi-definer define-crypto libcrypto #:default-make-fail make-not-available) (define-crypto AES_set_encrypt_key (_fun _pointer _int _AES_KEY-pointer -> _int)) ;;(define-crypto AES_set_decrypt_key (_fun _pointer _int _AES_KEY-pointer -> _int)) (define-crypto AES_ctr128_encrypt (_fun _pointer ;; in _pointer ;; out _long ;; length _AES_KEY-pointer ;; key _pointer ;; ivec, AES_BLOCK_SIZE bytes _pointer ;; ecount_buf, AES_BLOCK_SIZE bytes _pointer ;; int pointer, the "num" field of the ongoing state (??) -> _void)) (struct aes-ctr-state (key ivec ecount num) #:transparent) (define (start-aes-ctr key initialization-vector) (let ((key-buffer (malloc sizeof-AES_KEY)) (ivec (make-bytes AES_BLOCK_SIZE)) (ecount (make-bytes AES_BLOCK_SIZE)) (num (make-bytes (ctype-sizeof _int)))) (AES_set_encrypt_key key (* 8 (bytes-length key)) ;; measured in bits key-buffer) (bytes-copy! ivec 0 initialization-vector 0 AES_BLOCK_SIZE) (bytes-fill! ecount 0) (bytes-fill! num 0) (aes-ctr-state key-buffer ivec ecount num))) (define (aes-ctr-process! state input-block) (define block-length (bytes-length input-block)) (define output-block (make-bytes block-length)) (AES_ctr128_encrypt input-block output-block block-length (aes-ctr-state-key state) (aes-ctr-state-ivec state) (aes-ctr-state-ecount state) (aes-ctr-state-num state)) output-block)