@@ -44,7 +44,19 @@ module Block = struct
44
44
45
45
val encrypt : key :key -> iv :string -> string -> string
46
46
val decrypt : key :key -> iv :string -> string -> string
47
- val next_iv : iv :string -> string -> string
47
+ val next_iv : ?off : int -> string -> iv :string -> string
48
+
49
+ val encrypt_into : key :key -> iv :string -> string -> src_off :int ->
50
+ bytes -> dst_off :int -> int -> unit
51
+ val decrypt_into : key :key -> iv :string -> string -> src_off :int ->
52
+ bytes -> dst_off :int -> int -> unit
53
+
54
+ val unsafe_encrypt_into : key :key -> iv :string -> string -> src_off :int ->
55
+ bytes -> dst_off :int -> int -> unit
56
+ val unsafe_decrypt_into : key :key -> iv :string -> string -> src_off :int ->
57
+ bytes -> dst_off :int -> int -> unit
58
+ val unsafe_encrypt_into_inplace : key :key -> iv :string ->
59
+ bytes -> dst_off :int -> int -> unit
48
60
end
49
61
50
62
module type CTR = sig
@@ -187,40 +199,71 @@ module Modes = struct
187
199
188
200
let of_secret = Core. of_secret
189
201
190
- let bounds_check ~iv cs =
191
- if String. length iv <> block then invalid_arg " CBC: IV length %u" (String. length iv);
192
- if String. length cs mod block <> 0 then
193
- invalid_arg " CBC: argument length %u" (String. length cs)
202
+ let bounds_check ?(off = 0 ) ~iv cs =
203
+ if String. length iv <> block then
204
+ invalid_arg " CBC: IV length %u not of block size" (String. length iv);
205
+ if (String. length cs - off) mod block <> 0 then
206
+ invalid_arg " CBC: argument length %u (off %u) not of block size"
207
+ (String. length cs) off
194
208
195
- let next_iv ~ iv cs =
196
- bounds_check ~iv cs ;
197
- if String. length cs > 0 then
209
+ let next_iv ?( off = 0 ) cs ~ iv =
210
+ bounds_check ~iv cs ~off ;
211
+ if String. length cs > off then
198
212
String. sub cs (String. length cs - block_size) block_size
199
213
else iv
200
214
201
- let encrypt ~key :(key , _ ) ~iv src =
202
- bounds_check ~iv src ;
203
- let dst = Bytes. of_string src in
215
+ let unsafe_encrypt_into_inplace ~key :(key , _ ) ~iv dst ~dst_off len =
204
216
let rec loop iv iv_i dst_i = function
205
- 0 -> ()
206
- | b -> Native. xor_into_bytes iv iv_i dst dst_i block ;
207
- Core. encrypt ~key ~blocks: 1 (Bytes. unsafe_to_string dst) dst_i dst dst_i ;
208
- loop (Bytes. unsafe_to_string dst) dst_i (dst_i + block) (b - 1 )
217
+ | 0 -> ()
218
+ | b ->
219
+ Native. xor_into_bytes iv iv_i dst dst_i block ;
220
+ Core. encrypt ~key ~blocks: 1 (Bytes. unsafe_to_string dst) dst_i dst dst_i ;
221
+ loop (Bytes. unsafe_to_string dst) dst_i (dst_i + block) (b - 1 )
209
222
in
210
- loop iv 0 0 (Bytes. length dst / block) ;
223
+ loop iv 0 dst_off (len / block)
224
+
225
+ let unsafe_encrypt_into ~key ~iv src ~src_off dst ~dst_off len =
226
+ Bytes. unsafe_blit_string src src_off dst dst_off len;
227
+ unsafe_encrypt_into_inplace ~key ~iv dst ~dst_off len
228
+
229
+ let encrypt_into ~key ~iv src ~src_off dst ~dst_off len =
230
+ bounds_check ~off: src_off ~iv src;
231
+ if String. length src - src_off < len then
232
+ invalid_arg " CBC: src has insufficient length (%u - src_off:%u < len %u)"
233
+ (String. length src) src_off len;
234
+ if Bytes. length dst - dst_off < len then
235
+ invalid_arg " CBC: dst has insufficient length (%u - dst_off:%u < len %u)"
236
+ (Bytes. length dst) dst_off len;
237
+ unsafe_encrypt_into ~key ~iv src ~src_off dst ~dst_off len
238
+
239
+ let encrypt ~key ~iv src =
240
+ let dst = Bytes. create (String. length src) in
241
+ encrypt_into ~key ~iv src ~src_off: 0 dst ~dst_off: 0 (String. length src);
211
242
Bytes. unsafe_to_string dst
212
243
213
- let decrypt ~key :(_ , key ) ~iv src =
214
- bounds_check ~iv src ;
215
- let msg = Bytes. create (String. length src)
216
- and b = String. length src / block in
244
+ let unsafe_decrypt_into ~key :(_ , key ) ~iv src ~src_off dst ~dst_off len =
245
+ let b = len / block in
217
246
if b > 0 then begin
218
- Core. decrypt ~key ~blocks: b src 0 msg 0 ;
219
- Native. xor_into_bytes iv 0 msg 0 block ;
220
- Native. xor_into_bytes src 0 msg block ((b - 1 ) * block) ;
221
- end ;
222
- Bytes. unsafe_to_string msg
247
+ Core. decrypt ~key ~blocks: b src src_off dst dst_off ;
248
+ Native. xor_into_bytes iv 0 dst dst_off block ;
249
+ Native. xor_into_bytes src src_off dst (dst_off + block) ((b - 1 ) * block) ;
250
+ end
223
251
252
+ let decrypt_into ~key ~iv src ~src_off dst ~dst_off len =
253
+ bounds_check ~off: src_off ~iv src;
254
+ if String. length src - src_off < len then
255
+ invalid_arg " CBC: src has insufficient length (%u - src_off:%u < len %u)"
256
+ (String. length src) src_off len;
257
+ if Bytes. length dst - dst_off < len then
258
+ invalid_arg " CBC: dst has insufficient length (%u - dst_off:%u < len %u)"
259
+ (Bytes. length dst) dst_off len;
260
+ unsafe_decrypt_into ~key ~iv src ~src_off dst ~dst_off len
261
+
262
+ let decrypt ~key ~iv src =
263
+ let len = String. length src in
264
+ let msg = Bytes. create len in
265
+ decrypt_into ~key ~iv src ~src_off: 0 msg ~dst_off: 0 len;
266
+ Bytes. unsafe_to_string msg
224
267
end
225
268
226
269
module CTR_of (Core : Block.Core ) (Ctr : Counters.S ) :
0 commit comments