PR#3
PREFIX /A2OSX.BUILD
NEW
INC 1
AUTO 6
				.LIST OFF	
				.OP	65C02
				.OR	$2000
				.TF /A2OSX.BUILD/LIB/LIBCRYPT.O
*--------------------------------------
				.INB /A2OSX.BUILD/INC/MACROS.I
				.INB /A2OSX.BUILD/INC/A2OSX.I
				.INB /A2OSX.BUILD/INC/LIBCRYPT.I
*--------------------------------------
ZPTmpPtr1		.EQ ZPLIB
ZPTmpPtr2		.EQ ZPLIB+2
ZPTmpPtr3		.EQ ZPLIB+4
ZPTmpPtr4		.EQ ZPLIB+6
ZPDataPtr		.EQ ZPLIB+8
ZPDataLen		.EQ ZPLIB+10
ZPChunkLen		.EQ ZPLIB+12
*--------------------------------------
* DWORD Macros : Do NOT disturb carry with cpx, cpy...
*--------------------------------------
				.MA	ADC32
				ldx #3
				ldy #0
				clc
:1				lda ]1,y
				adc ]2,y
				sta ]3,y
				iny
				dex
				bpl :1
				.EM
*--------------------------------------
				.MA	AND32
				ldx #3
:1				lda ]1,x
				and ]2,x
				sta ]3,x
				dex
				bpl :1
				.EM
*--------------------------------------
				.MA	ORA32
				ldx #3
:1				lda ]1,x
				ora ]2,x
				sta ]3,x
				dex
				bpl :1
				.EM
*--------------------------------------
				.MA	EOR32
				ldx #3
:1				lda ]1,x
				eor ]2,x
				sta ]3,x
				dex
				bpl :1
				.EM
*--------------------------------------
				.MA	NOT32
				ldx #3
:1				lda ]1,x
				eor #$FF
				sta ]2,x
				dex
				bpl :1
				.EM
*--------------------------------------
				.MA	MOV32
				ldx #3
:1				lda ]1,x
				sta ]2,x
				dex
				bpl :1
				.EM
*--------------------------------------
				.MA	ROL32x
:2				lda ]1+3
				rol
				rol ]1
				rol ]1+1
				rol ]1+2
				rol ]1+3
				dex
				bne :2
				.EM
*--------------------------------------
*			File Header (16 Bytes)
*--------------------------------------
CS.START		cld
				jmp (.1,x)
				.DA #$61				6502,Level 1 (65c02)
				.DA #1					BIN Layout Version 1
				.DA 0
				.DA CS.END-CS.START
				.DA 0
				.DA 0
				.DA 0
*--------------------------------------
* Relocation Table
*--------------------------------------
.1				.DA LIB.LOAD
				.DA LIB.UNLOAD
				.DA MD5PStrA
				.DA MD5Init
				.DA MD5Update
				.DA MD5FinalizeA
				.DA 0
*--------------------------------------
LIB.LOAD
LIB.UNLOAD		clc
				rts
*--------------------------------------
* MD5PStrA
*  in :
*   A = hMem To PSTR
*  out :
*   A = hMem To MessageDigest
*--------------------------------------
MD5PStrA		>SYSCALL GetMemPtrA
				>STYA ZPTmpPtr3		1 and 2 used by other MD5 functions
				ldy #0
				lda (ZPTmpPtr3),y		get PStr len
				sta ZPTmpPtr4			ZPTmpPtr4 = str len
				stz ZPTmpPtr4+1		0,PSTR len <= 255
				inc ZPTmpPtr3
				bne .1
				inc ZPTmpPtr3+1		Make DATA skip PSTR Len Byte
.1				jsr MD5Init
				bcs .9
				pha						save MD5 Context hMem
				>PUSHW ZPTmpPtr4		Push LEN
				>PUSHW ZPTmpPtr3		Push DATA
				pla
				pha						
				>PUSHA					Push MD5 Context
				jsr MD5Update
				pla						get back MD5 Context
				pha
				jsr MD5FinalizeA
				plx						get back MD5 Context hMem
				pha						save MessageDigest hMem
				txa	
				>SYSCALL FreeMemA	Free MD5 Context
				pla						get back MessageDigest hMem
				clc
.9				rts
*--------------------------------------
* MD5Init
*  In :
*  Out :
*   A = hMem To S.MD5
*--------------------------------------
MD5Init			>LDYAI S.MD5.SIZE
				>SYSCALL GetMemYA
				bcs .9
				>STYA ZPTmpPtr1
				ldy #0
.1				lda MD5.ABCDINIT,y
				sta (ZPTmpPtr1),y
				iny
				cpy #16
				bne .1
				lda #0
.2				sta	(ZPTmpPtr1),y
				iny
				cpy #S.MD5.SIZE			Includes S.MD5.FINALIZED Flag
				bne .2
				txa
				clc
.9				rts
*--------------------------------------
* MD5Update (Append "$80" & Padding & original size)
*  In:
*	PULLB MD5 Context hMem
*	PULLW DATA PTR
*	PULLW DATA LEN
*--------------------------------------
MD5Update		>PULLA					get MD5 Context
				>SYSCALL GetMemPtrA
				>STYA ZPTmpPtr1		get MD5 Context
				>PULLW ZPDataPtr		get DATA
				>PULLW ZPDataLen		get LEN
				ldy #S.MD5.FINALIZED
				lda (ZPTmpPtr1),y
				beq .1
				sec
				rts
.1				lda ZPDataLen+1			More than 256 Bytes remaining to hash ?
				bne .3					yes
				lda ZPDataLen
				bne .2					Len = O ? 
				clc						All data processed
				rts
				
.2				cmp #64					More than 64 Bytes remaining to hash ?
				bcc .50					yes
.3				lda #64
.50				sta ZPChunkLen			Save Chunk Len
				jsr MD5UpdateBitCount
				ldy #0
.51				lda (ZPDataPtr),y		Load Buffer with data
				sta MD5.BUFFER64,y
				iny
				cpy ZPChunkLen
				bne .51
				cpy #64					Full 64 Bytes DATA ?
				beq .58
				lda #$80				no, Append $80
				sta MD5.BUFFER64,y
				lda #0
.52				iny						Pad with 0 to 64 
				cpy #64
				beq .53
				sta MD5.BUFFER64,y
				bra .52
.53				ldy #S.MD5.EXTRABIT		Mark MD5 Context as Appended
				lda #$80
				sta (ZPTmpPtr1),y
				lda ZPChunkLen
				cmp #56					Enough room for BITCOUNT ?
				bcs .58					no
				jsr MD5AppendBitCount
.58				jsr MD5Transform
				jsr MD5UpdateABCD0
.8				lda ZPDataLen			Substract Bytes processed from LEN
				sec
				sbc ZPChunkLen			get back chunk Len
				sta ZPDataLen
				bcs .81
				dec ZPDataLen+1
.81				lda ZPDataPtr			Add Bytes processed to DATA
				clc
				adc ZPChunkLen
				sta ZPDataPtr
				bcc .82
				inc ZPDataPtr+1
.82				bra .1
*--------------------------------------
* MD5FinalizeA
*  In : 
*    A = hMem To S.MD5
*  Out:
*    A = MessageDigest (PSTR, 16 Bytes, 32 Chars)
*--------------------------------------
MD5FinalizeA	>SYSCALL GetMemPtrA
				>STYA ZPTmpPtr1		get MD5 Context
				ldy #S.MD5.FINALIZED
				lda (ZPTmpPtr1),y
				bne .11
				jsr MD5ExtraChunk
.11				>LDYAI 33				Len + 32 Digits 
				>SYSCALL GetMemYA
				bcs .9
				>STYA ZPTmpPtr2
				phx						save hMem for return
				lda #32
				sta (ZPTmpPtr2)
				inc ZPTmpPtr2
				bne .10
				inc ZPTmpPtr2+1
.10				ldy #S.MD5.ABCD0
.1				lda (ZPTmpPtr1),y
				lsr
				lsr
				lsr
				lsr
				tax
				lda MD5.DIGITS,x
				sta (ZPTmpPtr2)
				inc ZPTmpPtr2
				bne .2
				inc ZPTmpPtr2+1
.2				lda (ZPTmpPtr1),y
				and #$0F
				tax
				lda MD5.DIGITS,x
				sta (ZPTmpPtr2)
				inc ZPTmpPtr2
				bne .3
				inc ZPTmpPtr2+1
.3				iny
				cpy #S.MD5.ABCD0+16
				bne .1
				pla						get back hMem
				clc
.9				rts
*--------------------------------------
*			PRIVATE
*--------------------------------------
* MD5AppendBitCount
*  In :
*   ZPTmpPtr1 = MD5 Context
*--------------------------------------
MD5AppendBitCount
				ldx #56
				ldy #S.MD5.BITCOUNT		Append 8 Bytes of BITCOUNT
.1				lda (ZPTmpPtr1),y
				sta MD5.BUFFER64,x
				inx
				iny
				cpy #S.MD5.BITCOUNT+8
				bne .1
				ldy #S.MD5.FINALIZED	Mark MD5 Context as Finalized
				lda #$80
				sta (ZPTmpPtr1),y
				rts
*--------------------------------------
* MD5UpdateBitCount
*  In :
*   CL = Size (in bytes) to add to MD5 context
*   ZPTmpPtr1 = MD5 Context
*--------------------------------------
MD5UpdateBitCount
				stz ZPChunkLen+1
				lda ZPChunkLen
				asl
				rol ZPChunkLen+1
				asl						times 8 to get bit count
				rol ZPChunkLen+1
				asl
				rol ZPChunkLen+1
				clc
				ldy #S.MD5.BITCOUNT
				adc (ZPTmpPtr1),y
				sta (ZPTmpPtr1),y
				iny
				lda ZPChunkLen+1
				adc (ZPTmpPtr1),y
				sta (ZPTmpPtr1),y
				bcc .8
.1				iny
				lda (ZPTmpPtr1),y
				inc
				sta (ZPTmpPtr1),y
				bne .8
				cpy #7
				bne .1
.8				rts				
*--------------------------------------
* MD5ExtraChunk
*  In : 
*   ZPTmpPtr1 = MD5 Context
*--------------------------------------
MD5ExtraChunk	ldy #S.MD5.FINALIZED
				lda #$80
				sta (ZPTmpPtr1),y		Mark MD5 Context as "finalized"
				ldx #0
				ldy #S.MD5.EXTRABIT		Extra Bit already appended ?
				lda (ZPTmpPtr1),y
				bne .1
				lda #$80
				sta MD5.BUFFER64		Add extra bit to buffer
				sta (ZPTmpPtr1),y		Mark Extrabit added
				inx
.1				stz MD5.BUFFER64,x		pad with "0"...
				inx
				cpx #56
				bne .1					...until room for bitcount
				jsr MD5AppendBitCount
				jsr MD5Transform
*--------------------------------------
* MD5UpdateABCD0
*  In: 
*   ZPTmpPtr1 = MD5 Context
*--------------------------------------
MD5UpdateABCD0	ldy #0
.1				clc						ADC32 A+A0->A0, B, C, D.... 
.2				lda MD5.ABCD,y
				adc (ZPTmpPtr1),y
				sta (ZPTmpPtr1),y
				iny
				tya
				and #3
				bne .2
				cpy #16
				bne .1
				rts
*--------------------------------------
* MD5Transform 
*  In: 
*   ZPTmpPtr1 = MD5 Context
*   512 Bits Padded chunk in MD5.BUFFER64
*  Out:
*   Updated MD5.ABCD
*--------------------------------------
MD5Transform	ldy #15					init ABCD Chunk with Context ABCD0
.1				lda (ZPTmpPtr1),y
				sta MD5.ABCD,y
				dey
				bpl .1
				stz MD5.i				Start Proceed 0 to 63 bytes
*--------------------------------------
MD5.0015		lda MD5.i
				cmp #16
				bcs MD5.1631
				>AND32 MD5.B,MD5.C,MD5.F1
				>NOT32 MD5.B,MD5.F2
				>AND32 MD5.F2,MD5.D,MD5.F2
				>ORA32 MD5.F1,MD5.F2,MD5.F
				jmp MD5.NEXTi
*--------------------------------------
MD5.1631		cmp #32
				bcs MD5.3247
				>AND32 MD5.D,MD5.B,MD5.F1
				>NOT32 MD5.D,MD5.F2
				>AND32 MD5.F2,MD5.C,MD5.F2
				>ORA32 MD5.F1,MD5.F2,MD5.F
				jmp MD5.NEXTi
*--------------------------------------
MD5.3247		cmp #48
				bcs MD5.4863
				>EOR32 MD5.B,MD5.C,MD5.F
				>EOR32 MD5.F,MD5.D,MD5.F
				jmp MD5.NEXTi
*--------------------------------------
MD5.4863		cmp #64
				bne .1 
				rts
.1				>NOT32 MD5.D,MD5.F1
				>ORA32 MD5.F1,MD5.B,MD5.F2
				>EOR32 MD5.F2,MD5.C,MD5.F
*--------------------------------------
MD5.NEXTi		>MOV32 MD5.D,MD5.DTemp
				>MOV32 MD5.C,MD5.D
				>MOV32 MD5.B,MD5.C
				>ADC32 MD5.A,MD5.F,MD5.F
				lda MD5.i
				asl
				asl
				tay
				ldx #0
				clc
.1				lda MD5.K,y 			ADC32 MD5.K[i],MD5.F,MD5.F
				adc MD5.F,x
				sta MD5.F,x
				iny
				inx
				txa
				eor #4					DO NOT DISTURB carry with cpx !!!
				bne .1
				ldy MD5.i
				lda MD5.g,y
				asl
				asl
				tay
				ldx #0
				clc
.2				lda MD5.BUFFER64,y		ADC32 M[g],MD5.F,MD5.F
				adc MD5.F,x
				sta MD5.F,x
				iny
				inx
				txa
				eor #4					DO NOT DISTURB carry with cpx !!!
				bne .2
				ldy MD5.i
				lda MD5.s,y				get s[i] in x
				tax
				>ROL32x MD5.F
				>ADC32 MD5.B,MD5.F,MD5.B
				>MOV32 MD5.DTemp,MD5.A
				inc MD5.i
				jmp MD5.0015
*--------------------------------------
CS.END
MD5.ABCD
MD5.A			.BS 4					Chunk Level,A,B,C,D
MD5.B			.BS 4
MD5.C			.BS 4
MD5.D			.BS 4
MD5.DTemp		.BS 4
MD5.F			.BS	4
MD5.F1			.BS	4
MD5.F2			.BS	4
MD5.i			.BS 1
MD5.BUFFER64	.BS 64
*--------------------------------------
MD5.ABCDINIT	.HS 01234567.89ABCDEF.FEDCBA98.76543210
*--------------------------------------
MD5.s			.DA #7,#12,#17,#22,#7,#12,#17,#22,#7,#12,#17,#22,#7,#12,#17,#22
				.DA #5,#9,#14,#20,#5,#9,#14,#20,#5,#9,#14,#20,#5,#9,#14,#20
				.DA #4,#11,#16,#23,#4,#11,#16,#23,#4,#11,#16,#23,#4,#11,#16,#23
				.DA #6,#10,#15,#21,#6,#10,#15,#21,#6,#10,#15,#21,#6,#10,#15,#21
*--------------------------------------
MD5.g			.DA #0,#1,#2,#3,#4,#5,#6,#7,#8,#9,#10,#11,#12,#13,#14,#15
				.DA #1,#6,#11,#0,#5,#10,#15,#4,#9,#14,#3,#8,#13,#2,#7,#12
				.DA #5,#8,#11,#14,#1,#4,#7,#10,#13,#0,#3,#6,#9,#12,#15,#2
				.DA #0,#7,#14,#5,#12,#3,#10,#1,#8,#15,#6,#13,#4,#11,#2,#9
*--------------------------------------
MD5.K			.HS 78A46AD7.56B7C7E8.DB702024.EECEBDC1
				.HS AF0F7CF5.2AC68747.134630A8.019546FD
				.HS D8988069.AFF7448B.B15BFFFF.BED75C89
				.HS 2211906B.937198FD.8E4379A6.2108B449
				.HS 62251EF6.40B340C0.515A5E26.AAC7B6E9
				.HS 5D102FD6.53144402.81E6A1D8.C8FBD3E7
				.HS E6CDE121.D60737C3.870DD5F4.ED145A45
				.HS 05E9E3A9.F8A3EFFC.D9026F67.8A4C2A8D
				.HS 4239FAFF.81F67187.22619D6D.0C38E5FD
				.HS 44EABEA4.A9CFDE4B.604BBBF6.70BCBFBE
				.HS C67E9B28.FA27A1EA.8530EFD4.051D8804
				.HS 39D0D4D9.E599DBE6.F87CA21F.6556ACC4
				.HS 442229F4.97FF2A43.A72394AB.39A093FC
				.HS C3595B65.92CC0C8F.7DF4EFFF.D15D8485
				.HS 4F7EA86F.E0E62CFE.144301A3.A111084E
				.HS 827E53F7.35F23ABD.BBD2D72A.91D386EB
*--------------------------------------
MD5.DIGITS		.AS "0123456789ABCDEF"
*--------------------------------------
MAN
SAVE /A2OSX.SRC/LIB/LIBCRYPT.S
ASM